From 09e7578b93c34a903cbdf00bdca6cefee7eb55e2 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Thu, 7 Nov 2019 17:46:44 -0800 Subject: [PATCH] Add performance tests for SyntaxVisitor to the test suite --- Package.swift | 3 +- .../Inputs/MinimalCollections.swift.input | 6058 +++++++++++++++++ .../VisitorPerformanceTests.swift | 54 + 3 files changed, 6114 insertions(+), 1 deletion(-) create mode 100644 Tests/PerformanceTest/Inputs/MinimalCollections.swift.input create mode 100644 Tests/PerformanceTest/VisitorPerformanceTests.swift diff --git a/Package.swift b/Package.swift index 645f5c663ad..78d974b442b 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,8 @@ let package = Package( .testTarget(name: "SwiftSyntaxTest", dependencies: ["SwiftSyntax"], exclude: ["Inputs"]), .target(name: "SwiftSyntaxBuilder", dependencies: ["SwiftSyntax"]), .testTarget(name: "SwiftSyntaxBuilderTest", dependencies: ["SwiftSyntaxBuilder"]), - .target(name: "lit-test-helper", dependencies: ["SwiftSyntax"]) + .target(name: "lit-test-helper", dependencies: ["SwiftSyntax"]), + .testTarget(name: "PerformanceTest", dependencies: ["SwiftSyntax"]) // Also see targets added below ] ) diff --git a/Tests/PerformanceTest/Inputs/MinimalCollections.swift.input b/Tests/PerformanceTest/Inputs/MinimalCollections.swift.input new file mode 100644 index 00000000000..686053df42e --- /dev/null +++ b/Tests/PerformanceTest/Inputs/MinimalCollections.swift.input @@ -0,0 +1,6058 @@ +// This file has been copied from the main Swift repository to serve as a target +// for performance evaluations of SwiftSyntax. + +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +import StdlibUnittest + +/// State shared by all generators of a MinimalSequence. +internal class _MinimalIteratorSharedState { + internal init(_ data: [T]) { + self.data = data + } + + internal let data: [T] + internal var i: Int = 0 + internal var underestimatedCount: Int = 0 +} + +//===----------------------------------------------------------------------===// +// MinimalIterator +//===----------------------------------------------------------------------===// + +/// An IteratorProtocol that implements the protocol contract in the most +/// narrow way possible. +/// +/// This generator will return `nil` only once. +public struct MinimalIterator : IteratorProtocol { + public init(_ s: S) where S.Element == T { + self._sharedState = _MinimalIteratorSharedState(Array(s)) + } + + public init(_ data: [T]) { + self._sharedState = _MinimalIteratorSharedState(data) + } + + internal init(_ _sharedState: _MinimalIteratorSharedState) { + self._sharedState = _sharedState + } + + public func next() -> T? { + if _sharedState.i == _sharedState.data.count { + return nil + } + defer { _sharedState.i += 1 } + return _sharedState.data[_sharedState.i] + } + + internal let _sharedState: _MinimalIteratorSharedState +} + +// A protocol to identify MinimalIterator. +public protocol _MinimalIterator {} +extension MinimalIterator : _MinimalIterator {} + +//===----------------------------------------------------------------------===// +// MinimalSequence +//===----------------------------------------------------------------------===// + +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) +} + +/// A Sequence that implements the protocol contract in the most +/// narrow way possible. +/// +/// This sequence is consumed when its generator is advanced. +public struct MinimalSequence : Sequence, CustomDebugStringConvertible { + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + let data = Array(elements) + self._sharedState = _MinimalIteratorSharedState(data) + + 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 let timesMakeIteratorCalled = ResettableValue(0) + + 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..<_sharedState.data.count]))" + } + + internal let _sharedState: _MinimalIteratorSharedState +} + +//===----------------------------------------------------------------------===// +// Index invalidation checking +//===----------------------------------------------------------------------===// + +internal enum _CollectionOperation : Equatable { + case reserveCapacity(capacity: Int) + case append + case appendContentsOf(count: Int) + case replaceRange(subRange: Range, replacementCount: Int) + case insert(atIndex: Int) + case insertContentsOf(atIndex: Int, count: Int) + case removeAtIndex(index: Int) + case removeLast + case removeRange(subRange: Range) + case removeAll(keepCapacity: Bool) + + internal func _applyTo( + elementsLastMutatedStateIds: [Int], + endIndexLastMutatedStateId: Int, + nextStateId: Int + ) -> ([Int], Int) { + var newElementsIds = elementsLastMutatedStateIds + var newEndIndexId = endIndexLastMutatedStateId + switch self { + case .reserveCapacity: + let invalidIndices = newElementsIds.indices + newElementsIds.replaceSubrange( + invalidIndices, + with: repeatElement(nextStateId, count: invalidIndices.count)) + newEndIndexId = nextStateId + + case .append: + newElementsIds.append(nextStateId) + newEndIndexId = nextStateId + + case .appendContentsOf(let count): + newElementsIds.append(contentsOf: + repeatElement(nextStateId, count: count)) + newEndIndexId = nextStateId + + case .replaceRange(let subRange, let replacementCount): + newElementsIds.replaceSubrange( + subRange, + with: repeatElement(nextStateId, count: replacementCount)) + + let invalidIndices = subRange.lowerBound.. Bool { + switch (lhs, rhs) { + case (.reserveCapacity(let lhsCapacity), .reserveCapacity(let rhsCapacity)): + return lhsCapacity == rhsCapacity + + case (.append, .append): + return true + + case (.appendContentsOf(let lhsCount), .appendContentsOf(let rhsCount)): + return lhsCount == rhsCount + + case ( + .replaceRange(let lhsSubRange, let lhsReplacementCount), + .replaceRange(let rhsSubRange, let rhsReplacementCount)): + + return lhsSubRange == rhsSubRange && + lhsReplacementCount == rhsReplacementCount + + case (.insert(let lhsAtIndex), .insert(let rhsAtIndex)): + return lhsAtIndex == rhsAtIndex + + case ( + .insertContentsOf(let lhsAtIndex, let lhsCount), + .insertContentsOf(let rhsAtIndex, let rhsCount)): + + return lhsAtIndex == rhsAtIndex && lhsCount == rhsCount + + case (.removeAtIndex(let lhsIndex), .removeAtIndex(let rhsIndex)): + return lhsIndex == rhsIndex + + case (.removeLast, .removeLast): + return true + + case (.removeRange(let lhsSubRange), .removeRange(let rhsSubRange)): + return lhsSubRange == rhsSubRange + + case (.removeAll(let lhsKeepCapacity), .removeAll(let rhsKeepCapacity)): + return lhsKeepCapacity == rhsKeepCapacity + + default: + return false + } +} + +public struct _CollectionState : Equatable, Hashable { + internal static var _nextUnusedState: Int = 0 + internal static var _namedStates: [String : _CollectionState] = [:] + + internal let _id: Int + internal let _elementsLastMutatedStateIds: [Int] + internal let _endIndexLastMutatedStateId: Int + + internal init( + id: Int, + elementsLastMutatedStateIds: [Int], + endIndexLastMutatedStateId: Int) { + self._id = id + self._elementsLastMutatedStateIds = elementsLastMutatedStateIds + self._endIndexLastMutatedStateId = endIndexLastMutatedStateId + } + + public init(newRootStateForElementCount count: Int) { + self._id = _CollectionState._nextUnusedState + _CollectionState._nextUnusedState += 1 + self._elementsLastMutatedStateIds = + Array(repeatElement(self._id, count: count)) + self._endIndexLastMutatedStateId = self._id + } + + internal init(name: String, elementCount: Int) { + if let result = _CollectionState._namedStates[name] { + self = result + } else { + self = _CollectionState(newRootStateForElementCount: elementCount) + _CollectionState._namedStates[name] = self + } + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(_id) + } +} + +public func == (lhs: _CollectionState, rhs: _CollectionState) -> Bool { + return lhs._id == rhs._id +} + +internal struct _CollectionStateTransition { + internal let _previousState: _CollectionState + internal let _operation: _CollectionOperation + internal let _nextState: _CollectionState + + internal static var _allTransitions: + [_CollectionState : Box<[_CollectionStateTransition]>] = [:] + + internal init( + previousState: _CollectionState, + operation: _CollectionOperation, + nextState: _CollectionState + ) { + var transitions = + _CollectionStateTransition._allTransitions[previousState] + if transitions == nil { + transitions = Box<[_CollectionStateTransition]>([]) + _CollectionStateTransition._allTransitions[previousState] = transitions + } + if let i = transitions!.value.firstIndex(where: { $0._operation == operation }) { + self = transitions!.value[i] + return + } + self._previousState = previousState + self._operation = operation + self._nextState = nextState + transitions!.value.append(self) + } + + internal init( + previousState: _CollectionState, + operation: _CollectionOperation + ) { + let nextStateId = _CollectionState._nextUnusedState + _CollectionState._nextUnusedState += 1 + let (newElementStates, newEndIndexState) = operation._applyTo( + elementsLastMutatedStateIds: previousState._elementsLastMutatedStateIds, + endIndexLastMutatedStateId: previousState._endIndexLastMutatedStateId, + nextStateId: nextStateId) + let nextState = _CollectionState( + id: nextStateId, + elementsLastMutatedStateIds: newElementStates, + endIndexLastMutatedStateId: newEndIndexState) + self = _CollectionStateTransition( + previousState: previousState, + operation: operation, + nextState: nextState) + } +} + + +//===----------------------------------------------------------------------===// +// MinimalIndex +//===----------------------------------------------------------------------===// + +/// Asserts that the two indices are allowed to participate in a binary +/// operation. +internal func _expectCompatibleIndices( + _ first: MinimalIndex, + _ second: MinimalIndex, + + _ message: @autoclosure () -> String = "", + stackTrace: SourceLocStack = SourceLocStack(), + showFrame: Bool = true, + file: String = #file, line: UInt = #line +) { + if first._collectionState._id == second._collectionState._id { + // Fast path: the indices are derived from the same state. + return + } + + // The indices are derived from different states. Check that they point + // to a self-consistent view of the collection. + if first._collectionState._id > second._collectionState._id { + return _expectCompatibleIndices(second, first) + } + + func lastMutatedStateId( + of i: MinimalIndex, + in state: _CollectionState + ) -> Int { + let offset = i.position + if offset == state._elementsLastMutatedStateIds.endIndex { + return state._id + } + return state._elementsLastMutatedStateIds[offset] + } + + let newestCollectionState = second._collectionState + let expectedFirstIndexLastMutatedStateId = + lastMutatedStateId(of: first, in: newestCollectionState) + + expectEqual( + expectedFirstIndexLastMutatedStateId, + first._collectionState._id, + "Indices are not compatible:\n" + + "first: \(first)\n" + + "second: \(second)\n" + + "first element last mutated in state id: \(first._collectionState._id)\n" + + "expected state id: \(expectedFirstIndexLastMutatedStateId)\n" + + "newest collection state: \(newestCollectionState)", + stackTrace: stackTrace.pushIf(showFrame, file: file, line: line)) + + // To make writing assertions easier, perform a trap. + if expectedFirstIndexLastMutatedStateId != first._collectionState._id { + fatalError("Indices are not compatible") + } +} + +public struct MinimalIndex : Comparable { + public init( + collectionState: _CollectionState, + position: Int, + startIndex: Int, + endIndex: Int + ) { + expectTrapping( + position, + in: startIndex...endIndex) + self = MinimalIndex( + _collectionState: collectionState, + uncheckedPosition: position) + } + + internal init( + _collectionState: _CollectionState, + uncheckedPosition: Int + ) { + self._collectionState = _collectionState + self.position = uncheckedPosition + } + + public let _collectionState: _CollectionState + public let position: Int + + public static var trapOnRangeCheckFailure = ResettableValue(true) + +} + +public func == (lhs: MinimalIndex, rhs: MinimalIndex) -> Bool { + _expectCompatibleIndices(lhs, rhs) + return lhs.position == rhs.position +} + +public func < (lhs: MinimalIndex, rhs: MinimalIndex) -> Bool { + _expectCompatibleIndices(lhs, rhs) + return lhs.position < rhs.position +} + + +//===----------------------------------------------------------------------===// +// MinimalStrideableIndex +//===----------------------------------------------------------------------===// + +/// Asserts that the two indices are allowed to participate in a binary +/// operation. +internal func _expectCompatibleIndices( + _ first: MinimalStrideableIndex, + _ second: MinimalStrideableIndex, + + _ message: @autoclosure () -> String = "", + stackTrace: SourceLocStack = SourceLocStack(), + showFrame: Bool = true, + file: String = #file, line: UInt = #line +) { + if first._collectionState._id == second._collectionState._id { + // Fast path: the indices are derived from the same state. + return + } + + // The indices are derived from different states. Check that they point + // to a self-consistent view of the collection. + if first._collectionState._id > second._collectionState._id { + return _expectCompatibleIndices(second, first) + } + + func lastMutatedStateId( + of i: MinimalStrideableIndex, + in state: _CollectionState + ) -> Int { + let offset = i.position + if offset == state._elementsLastMutatedStateIds.endIndex { + return state._id + } + return state._elementsLastMutatedStateIds[offset] + } + + let newestCollectionState = second._collectionState + let expectedFirstIndexLastMutatedStateId = + lastMutatedStateId(of: first, in: newestCollectionState) + + expectEqual( + expectedFirstIndexLastMutatedStateId, + first._collectionState._id, + "Indices are not compatible:\n" + + "first: \(first)\n" + + "second: \(second)\n" + + "first element last mutated in state id: \(first._collectionState._id)\n" + + "expected state id: \(expectedFirstIndexLastMutatedStateId)\n" + + "newest collection state: \(newestCollectionState)", + stackTrace: stackTrace.pushIf(showFrame, file: file, line: line)) + + // To make writing assertions easier, perform a trap. + if expectedFirstIndexLastMutatedStateId != first._collectionState._id { + fatalError("Indices are not compatible") + } +} + +public struct MinimalStrideableIndex : Comparable { + public init( + collectionState: _CollectionState, + position: Int, + startIndex: Int, + endIndex: Int + ) { + expectTrapping( + position, + in: startIndex...endIndex) + self = MinimalStrideableIndex( + _collectionState: collectionState, + uncheckedPosition: position) + } + + internal init( + _collectionState: _CollectionState, + uncheckedPosition: Int + ) { + self._collectionState = _collectionState + self.position = uncheckedPosition + } + + public let _collectionState: _CollectionState + public let position: Int + + public static var trapOnRangeCheckFailure = ResettableValue(true) + + public var timesAdvancedCalled = ResettableValue(0) + public var timesDistanceCalled = ResettableValue(0) +} + +public func == (lhs: MinimalStrideableIndex, rhs: MinimalStrideableIndex) -> Bool { + _expectCompatibleIndices(lhs, rhs) + return lhs.position == rhs.position +} + +public func < (lhs: MinimalStrideableIndex, rhs: MinimalStrideableIndex) -> Bool { + _expectCompatibleIndices(lhs, rhs) + return lhs.position < rhs.position +} + + +extension MinimalStrideableIndex : Strideable { + public typealias Stride = Int + + public func distance(to other: MinimalStrideableIndex) -> Int { + timesDistanceCalled.value += 1 + _expectCompatibleIndices(self, other) + return other.position - position + } + + public func advanced(by n: Int) -> MinimalStrideableIndex { + timesAdvancedCalled.value += 1 + return MinimalStrideableIndex( + _collectionState: _collectionState, + uncheckedPosition: position + n) + } +} + +//===----------------------------------------------------------------------===// +// Minimal***[Mutable]?Collection +//===----------------------------------------------------------------------===// + + +/// A minimal implementation of `Collection` with extra checks. +public struct MinimalCollection : Collection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. Int { + precondition(start <= end, + "Only BidirectionalCollections can have end come before start") + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + precondition(n >= 0, + "Only BidirectionalCollections can be advanced by a negative amount") + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex.. : Collection, RangeReplaceableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + public init() { + self.underestimatedCount = 0 + self._elements = [] + self._collectionState = + _CollectionState(name: "\(type(of: self))", elementCount: 0) + } + + public init(_ elements: S) where S.Element == T { + self.underestimatedCount = 0 + self._elements = Array(elements) + self._collectionState = + _CollectionState(newRootStateForElementCount: self._elements.count) + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. Int { + precondition(start <= end, + "Only BidirectionalCollections can have end come before start") + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + precondition(n >= 0, + "Only BidirectionalCollections can be advanced by a negative amount") + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex..(contentsOf newElements: S) + where S.Element == T { + let oldCount = count + _elements.append(contentsOf: newElements) + let newCount = count + _willMutate(.appendContentsOf(count: newCount - oldCount)) + } + + public mutating func replaceSubrange( + _ subRange: Range, + with newElements: C + ) where C : Collection, C.Element == T { + let oldCount = count + _elements.replaceSubrange( + subRange.lowerBound.position..( + contentsOf newElements: S, at i: MinimalIndex + ) where S.Element == T { + let oldCount = count + _elements.insert(contentsOf: newElements, at: i.position) + let newCount = count + + if newCount - oldCount != 0 { + _willMutate(.insertContentsOf( + atIndex: i.position, + count: newCount - oldCount)) + } + } + + @discardableResult + public mutating func remove(at i: MinimalIndex) -> T { + _willMutate(.removeAtIndex(index: i.position)) + return _elements.remove(at: i.position) + } + + @discardableResult + public mutating func removeLast() -> T { + _willMutate(.removeLast) + return _elements.removeLast() + } + + public mutating func removeSubrange(_ subRange: Range) { + if !subRange.isEmpty { + _willMutate(.removeRange( + subRange: subRange.lowerBound.position.. : Collection, MutableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. Int { + precondition(start <= end, + "Only BidirectionalCollections can have end come before start") + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + precondition(n >= 0, + "Only BidirectionalCollections can be advanced by a negative amount") + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex.. : Collection, MutableCollection, RangeReplaceableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + public init() { + self.underestimatedCount = 0 + self._elements = [] + self._collectionState = + _CollectionState(name: "\(type(of: self))", elementCount: 0) + } + + public init(_ elements: S) where S.Element == T { + self.underestimatedCount = 0 + self._elements = Array(elements) + self._collectionState = + _CollectionState(newRootStateForElementCount: self._elements.count) + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. Int { + precondition(start <= end, + "Only BidirectionalCollections can have end come before start") + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + precondition(n >= 0, + "Only BidirectionalCollections can be advanced by a negative amount") + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex..(contentsOf newElements: S) + where S.Element == T { + let oldCount = count + _elements.append(contentsOf: newElements) + let newCount = count + _willMutate(.appendContentsOf(count: newCount - oldCount)) + } + + public mutating func replaceSubrange( + _ subRange: Range, + with newElements: C + ) where C : Collection, C.Element == T { + let oldCount = count + _elements.replaceSubrange( + subRange.lowerBound.position..( + contentsOf newElements: S, at i: MinimalIndex + ) where S.Element == T { + let oldCount = count + _elements.insert(contentsOf: newElements, at: i.position) + let newCount = count + + if newCount - oldCount != 0 { + _willMutate(.insertContentsOf( + atIndex: i.position, + count: newCount - oldCount)) + } + } + + @discardableResult + public mutating func remove(at i: MinimalIndex) -> T { + _willMutate(.removeAtIndex(index: i.position)) + return _elements.remove(at: i.position) + } + + @discardableResult + public mutating func removeLast() -> T { + _willMutate(.removeLast) + return _elements.removeLast() + } + + public mutating func removeSubrange(_ subRange: Range) { + if !subRange.isEmpty { + _willMutate(.removeRange( + subRange: subRange.lowerBound.position.. : BidirectionalCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex.. : BidirectionalCollection, RangeReplaceableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + public init() { + self.underestimatedCount = 0 + self._elements = [] + self._collectionState = + _CollectionState(name: "\(type(of: self))", elementCount: 0) + } + + public init(_ elements: S) where S.Element == T { + self.underestimatedCount = 0 + self._elements = Array(elements) + self._collectionState = + _CollectionState(newRootStateForElementCount: self._elements.count) + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex..(contentsOf newElements: S) + where S.Element == T { + let oldCount = count + _elements.append(contentsOf: newElements) + let newCount = count + _willMutate(.appendContentsOf(count: newCount - oldCount)) + } + + public mutating func replaceSubrange( + _ subRange: Range, + with newElements: C + ) where C : Collection, C.Element == T { + let oldCount = count + _elements.replaceSubrange( + subRange.lowerBound.position..( + contentsOf newElements: S, at i: MinimalIndex + ) where S.Element == T { + let oldCount = count + _elements.insert(contentsOf: newElements, at: i.position) + let newCount = count + + if newCount - oldCount != 0 { + _willMutate(.insertContentsOf( + atIndex: i.position, + count: newCount - oldCount)) + } + } + + @discardableResult + public mutating func remove(at i: MinimalIndex) -> T { + _willMutate(.removeAtIndex(index: i.position)) + return _elements.remove(at: i.position) + } + + @discardableResult + public mutating func removeLast() -> T { + _willMutate(.removeLast) + return _elements.removeLast() + } + + public mutating func removeSubrange(_ subRange: Range) { + if !subRange.isEmpty { + _willMutate(.removeRange( + subRange: subRange.lowerBound.position.. : BidirectionalCollection, MutableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex.. : BidirectionalCollection, MutableCollection, RangeReplaceableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + public init() { + self.underestimatedCount = 0 + self._elements = [] + self._collectionState = + _CollectionState(name: "\(type(of: self))", elementCount: 0) + } + + public init(_ elements: S) where S.Element == T { + self.underestimatedCount = 0 + self._elements = Array(elements) + self._collectionState = + _CollectionState(newRootStateForElementCount: self._elements.count) + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex..(contentsOf newElements: S) + where S.Element == T { + let oldCount = count + _elements.append(contentsOf: newElements) + let newCount = count + _willMutate(.appendContentsOf(count: newCount - oldCount)) + } + + public mutating func replaceSubrange( + _ subRange: Range, + with newElements: C + ) where C : Collection, C.Element == T { + let oldCount = count + _elements.replaceSubrange( + subRange.lowerBound.position..( + contentsOf newElements: S, at i: MinimalIndex + ) where S.Element == T { + let oldCount = count + _elements.insert(contentsOf: newElements, at: i.position) + let newCount = count + + if newCount - oldCount != 0 { + _willMutate(.insertContentsOf( + atIndex: i.position, + count: newCount - oldCount)) + } + } + + @discardableResult + public mutating func remove(at i: MinimalIndex) -> T { + _willMutate(.removeAtIndex(index: i.position)) + return _elements.remove(at: i.position) + } + + @discardableResult + public mutating func removeLast() -> T { + _willMutate(.removeLast) + return _elements.removeLast() + } + + public mutating func removeSubrange(_ subRange: Range) { + if !subRange.isEmpty { + _willMutate(.removeRange( + subRange: subRange.lowerBound.position.. : RandomAccessCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + // FIXME: this shouldn't be necessary, should come by default + public typealias Indices = DefaultIndices> + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex.. : RandomAccessCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalStrideableIndex + + internal func _index(forPosition i: Int) -> MinimalStrideableIndex { + return MinimalStrideableIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalStrideableIndex { + return MinimalStrideableIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalStrideableIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalStrideableIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + public typealias Indices = Range + + public func _failEarlyRangeCheck( + _ index: MinimalStrideableIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalStrideableIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalStrideableIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalStrideableIndex, to end: MinimalStrideableIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex.. : RandomAccessCollection, RangeReplaceableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + public init() { + self.underestimatedCount = 0 + self._elements = [] + self._collectionState = + _CollectionState(name: "\(type(of: self))", elementCount: 0) + } + + public init(_ elements: S) where S.Element == T { + self.underestimatedCount = 0 + self._elements = Array(elements) + self._collectionState = + _CollectionState(newRootStateForElementCount: self._elements.count) + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + // FIXME: this shouldn't be necessary, should come by default + public typealias Indices = DefaultIndices> + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex..(contentsOf newElements: S) + where S.Element == T { + let oldCount = count + _elements.append(contentsOf: newElements) + let newCount = count + _willMutate(.appendContentsOf(count: newCount - oldCount)) + } + + public mutating func replaceSubrange( + _ subRange: Range, + with newElements: C + ) where C : Collection, C.Element == T { + let oldCount = count + _elements.replaceSubrange( + subRange.lowerBound.position..( + contentsOf newElements: S, at i: MinimalIndex + ) where S.Element == T { + let oldCount = count + _elements.insert(contentsOf: newElements, at: i.position) + let newCount = count + + if newCount - oldCount != 0 { + _willMutate(.insertContentsOf( + atIndex: i.position, + count: newCount - oldCount)) + } + } + + @discardableResult + public mutating func remove(at i: MinimalIndex) -> T { + _willMutate(.removeAtIndex(index: i.position)) + return _elements.remove(at: i.position) + } + + @discardableResult + public mutating func removeLast() -> T { + _willMutate(.removeLast) + return _elements.removeLast() + } + + public mutating func removeSubrange(_ subRange: Range) { + if !subRange.isEmpty { + _willMutate(.removeRange( + subRange: subRange.lowerBound.position.. : RandomAccessCollection, RangeReplaceableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + public init() { + self.underestimatedCount = 0 + self._elements = [] + self._collectionState = + _CollectionState(name: "\(type(of: self))", elementCount: 0) + } + + public init(_ elements: S) where S.Element == T { + self.underestimatedCount = 0 + self._elements = Array(elements) + self._collectionState = + _CollectionState(newRootStateForElementCount: self._elements.count) + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalStrideableIndex + + internal func _index(forPosition i: Int) -> MinimalStrideableIndex { + return MinimalStrideableIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalStrideableIndex { + return MinimalStrideableIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalStrideableIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalStrideableIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + public typealias Indices = Range + + public func _failEarlyRangeCheck( + _ index: MinimalStrideableIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalStrideableIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalStrideableIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalStrideableIndex, to end: MinimalStrideableIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex..(contentsOf newElements: S) + where S.Element == T { + let oldCount = count + _elements.append(contentsOf: newElements) + let newCount = count + _willMutate(.appendContentsOf(count: newCount - oldCount)) + } + + public mutating func replaceSubrange( + _ subRange: Range, + with newElements: C + ) where C : Collection, C.Element == T { + let oldCount = count + _elements.replaceSubrange( + subRange.lowerBound.position..( + contentsOf newElements: S, at i: MinimalStrideableIndex + ) where S.Element == T { + let oldCount = count + _elements.insert(contentsOf: newElements, at: i.position) + let newCount = count + + if newCount - oldCount != 0 { + _willMutate(.insertContentsOf( + atIndex: i.position, + count: newCount - oldCount)) + } + } + + @discardableResult + public mutating func remove(at i: MinimalStrideableIndex) -> T { + _willMutate(.removeAtIndex(index: i.position)) + return _elements.remove(at: i.position) + } + + @discardableResult + public mutating func removeLast() -> T { + _willMutate(.removeLast) + return _elements.removeLast() + } + + public mutating func removeSubrange(_ subRange: Range) { + if !subRange.isEmpty { + _willMutate(.removeRange( + subRange: subRange.lowerBound.position.. : RandomAccessCollection, MutableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + // FIXME: this shouldn't be necessary, should come by default + public typealias Indices = DefaultIndices> + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex.. : RandomAccessCollection, MutableCollection, RangeReplaceableCollection { + /// Creates a collection with given contents, but a unique modification + /// history. No other instance has the same modification history. + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == T { + self._elements = Array(elements) + + self._collectionState = _CollectionState( + newRootStateForElementCount: self._elements.count) + + switch underestimatedCount { + case .precise: + self.underestimatedCount = _elements.count + + case .half: + self.underestimatedCount = _elements.count / 2 + + case .overestimate: + self.underestimatedCount = _elements.count * 3 + 5 + + case .value(let count): + self.underestimatedCount = count + } + } + + public init() { + self.underestimatedCount = 0 + self._elements = [] + self._collectionState = + _CollectionState(name: "\(type(of: self))", elementCount: 0) + } + + public init(_ elements: S) where S.Element == T { + self.underestimatedCount = 0 + self._elements = Array(elements) + self._collectionState = + _CollectionState(newRootStateForElementCount: self._elements.count) + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return MinimalIterator(_elements) + } + + public typealias Index = MinimalIndex + + internal func _index(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + collectionState: _collectionState, + position: i, + startIndex: _elements.startIndex, + endIndex: _elements.endIndex) + } + + internal func _uncheckedIndex(forPosition i: Int) -> MinimalIndex { + return MinimalIndex( + _collectionState: _collectionState, + uncheckedPosition: i) + } + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.startIndex) + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return _uncheckedIndex(forPosition: _elements.endIndex) + } + + // FIXME: this shouldn't be necessary, should come by default + public typealias Indices = DefaultIndices> + + public func _failEarlyRangeCheck( + _ index: MinimalIndex, + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: index.position), + index) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + index.position, + in: bounds.lowerBound.position.., + bounds: Range + ) { + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.lowerBound.position), + range.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: range.upperBound.position), + range.upperBound) + + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.lowerBound.position), + bounds.lowerBound) + _expectCompatibleIndices( + _uncheckedIndex(forPosition: bounds.upperBound.position), + bounds.upperBound) + + expectTrapping( + range.lowerBound.position.. MinimalIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. MinimalIndex { + // FIXME: swift-3-indexing-model: perform a range check and use + // return _uncheckedIndex(forPosition: i.position - 1) + return _index(forPosition: i.position - 1) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + // FIXME: swift-3-indexing-model: perform a range check properly. + if start != endIndex { + _failEarlyRangeCheck(start, bounds: startIndex.. Index { + // FIXME: swift-3-indexing-model: perform a range check properly. + if i != endIndex { + _failEarlyRangeCheck(i, bounds: startIndex.. T { + get { + _failEarlyRangeCheck(i, bounds: startIndex..) -> Slice> { + get { + _failEarlyRangeCheck(bounds, bounds: startIndex..(contentsOf newElements: S) + where S.Element == T { + let oldCount = count + _elements.append(contentsOf: newElements) + let newCount = count + _willMutate(.appendContentsOf(count: newCount - oldCount)) + } + + public mutating func replaceSubrange( + _ subRange: Range, + with newElements: C + ) where C : Collection, C.Element == T { + let oldCount = count + _elements.replaceSubrange( + subRange.lowerBound.position..( + contentsOf newElements: S, at i: MinimalIndex + ) where S.Element == T { + let oldCount = count + _elements.insert(contentsOf: newElements, at: i.position) + let newCount = count + + if newCount - oldCount != 0 { + _willMutate(.insertContentsOf( + atIndex: i.position, + count: newCount - oldCount)) + } + } + + @discardableResult + public mutating func remove(at i: MinimalIndex) -> T { + _willMutate(.removeAtIndex(index: i.position)) + return _elements.remove(at: i.position) + } + + @discardableResult + public mutating func removeLast() -> T { + _willMutate(.removeLast) + return _elements.removeLast() + } + + public mutating func removeSubrange(_ subRange: Range) { + if !subRange.isEmpty { + _willMutate(.removeRange( + subRange: subRange.lowerBound.position.. : Sequence { + public let base: MinimalSequence + + public init(base: MinimalSequence) { + self.base = base + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: MinimalSequence( + elements: elements, underestimatedCount: underestimatedCount)) + } + + public func makeIterator() -> MinimalIterator { + return base.makeIterator() + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } +} + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedCollection : Collection { + public typealias Base = MinimalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + + public let base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + } + +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedForwardRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedForwardRangeReplaceableSlice + public typealias Base = MinimalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedForwardRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedForwardRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedForwardRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedRangeReplaceableCollection : Collection, RangeReplaceableCollection { + public typealias Base = MinimalRangeReplaceableCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalRangeReplaceableCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + } + + public init() { + base = Base() + } + + public mutating func replaceSubrange( + _ subRange: Range.Index>, + with newElements: C + ) where C : Collection, C.Element == Element { + base.replaceSubrange(subRange, with: newElements) + } +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedForwardRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedForwardRangeReplaceableSlice + public typealias Base = MinimalRangeReplaceableCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedForwardRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedForwardRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedForwardRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedMutableCollection : Collection, MutableCollection { + public typealias Base = MinimalMutableCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalMutableCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + set { + base[i] = newValue + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + set { + _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) + } + } + +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedForwardRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedForwardRangeReplaceableSlice + public typealias Base = MinimalMutableCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedForwardRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedForwardRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedForwardRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedMutableRangeReplaceableCollection : Collection, MutableCollection, RangeReplaceableCollection { + public typealias Base = MinimalMutableRangeReplaceableCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalMutableRangeReplaceableCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + set { + base[i] = newValue + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + set { + _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) + } + } + + public init() { + base = Base() + } + + public mutating func replaceSubrange( + _ subRange: Range.Index>, + with newElements: C + ) where C : Collection, C.Element == Element { + base.replaceSubrange(subRange, with: newElements) + } +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedForwardRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedForwardRangeReplaceableSlice + public typealias Base = MinimalMutableRangeReplaceableCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedForwardRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedForwardRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedForwardRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedBidirectionalCollection : BidirectionalCollection { + public typealias Base = MinimalBidirectionalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + + public let base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalBidirectionalCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + public let timesPredecessorCalled = ResettableValue(0) + + public func index(before i: MinimalIndex) -> MinimalIndex { + timesPredecessorCalled.value += 1 + return base.index(before: i) + } + + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + } + +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedBidirectionalRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedBidirectionalRangeReplaceableSlice + public typealias Base = MinimalBidirectionalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedBidirectionalRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedBidirectionalRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedBidirectionalRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedRangeReplaceableBidirectionalCollection : BidirectionalCollection, RangeReplaceableCollection { + public typealias Base = MinimalRangeReplaceableBidirectionalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalRangeReplaceableBidirectionalCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + public let timesPredecessorCalled = ResettableValue(0) + + public func index(before i: MinimalIndex) -> MinimalIndex { + timesPredecessorCalled.value += 1 + return base.index(before: i) + } + + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + } + + public init() { + base = Base() + } + + public mutating func replaceSubrange( + _ subRange: Range.Index>, + with newElements: C + ) where C : Collection, C.Element == Element { + base.replaceSubrange(subRange, with: newElements) + } +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedBidirectionalRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedBidirectionalRangeReplaceableSlice + public typealias Base = MinimalRangeReplaceableBidirectionalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedBidirectionalRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedBidirectionalRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedBidirectionalRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedMutableBidirectionalCollection : BidirectionalCollection, MutableCollection { + public typealias Base = MinimalMutableBidirectionalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalMutableBidirectionalCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + public let timesPredecessorCalled = ResettableValue(0) + + public func index(before i: MinimalIndex) -> MinimalIndex { + timesPredecessorCalled.value += 1 + return base.index(before: i) + } + + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + set { + base[i] = newValue + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + set { + _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) + } + } + +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedBidirectionalRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedBidirectionalRangeReplaceableSlice + public typealias Base = MinimalMutableBidirectionalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedBidirectionalRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedBidirectionalRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedBidirectionalRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedMutableRangeReplaceableBidirectionalCollection : BidirectionalCollection, MutableCollection, RangeReplaceableCollection { + public typealias Base = MinimalMutableRangeReplaceableBidirectionalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + public let timesPredecessorCalled = ResettableValue(0) + + public func index(before i: MinimalIndex) -> MinimalIndex { + timesPredecessorCalled.value += 1 + return base.index(before: i) + } + + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + set { + base[i] = newValue + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + set { + _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) + } + } + + public init() { + base = Base() + } + + public mutating func replaceSubrange( + _ subRange: Range.Index>, + with newElements: C + ) where C : Collection, C.Element == Element { + base.replaceSubrange(subRange, with: newElements) + } +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedBidirectionalRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedBidirectionalRangeReplaceableSlice + public typealias Base = MinimalMutableRangeReplaceableBidirectionalCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedBidirectionalRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedBidirectionalRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedBidirectionalRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedRandomAccessCollection : RandomAccessCollection { + public typealias Base = MinimalRandomAccessCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + // FIXME: this shouldn't be necessary, should come by default + public typealias Indices = DefaultIndices> + + public let base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalRandomAccessCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + public let timesPredecessorCalled = ResettableValue(0) + + public func index(before i: MinimalIndex) -> MinimalIndex { + timesPredecessorCalled.value += 1 + return base.index(before: i) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + return base.distance(from: start, to: end) + } + + public func index(_ i: Index, offsetBy n: Int) -> Index { + return base.index(i, offsetBy: n) + } + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + } + +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedRandomAccessRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedRandomAccessRangeReplaceableSlice + public typealias Base = MinimalRandomAccessCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedRandomAccessRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedRandomAccessCollectionWithStrideableIndex : RandomAccessCollection { + public typealias Base = MinimalRandomAccessCollectionWithStrideableIndex + public typealias Iterator = MinimalIterator + public typealias Index = MinimalStrideableIndex + + public typealias Indices = Range + + public let base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalRandomAccessCollectionWithStrideableIndex(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalStrideableIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalStrideableIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalStrideableIndex) -> Element { + get { + return base[i] + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + } + +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedRandomAccessRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedRandomAccessRangeReplaceableSlice + public typealias Base = MinimalRandomAccessCollectionWithStrideableIndex + public typealias Iterator = MinimalIterator + public typealias Index = MinimalStrideableIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedRandomAccessRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedRangeReplaceableRandomAccessCollection : RandomAccessCollection, RangeReplaceableCollection { + public typealias Base = MinimalRangeReplaceableRandomAccessCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + // FIXME: this shouldn't be necessary, should come by default + public typealias Indices = DefaultIndices> + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalRangeReplaceableRandomAccessCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + public let timesPredecessorCalled = ResettableValue(0) + + public func index(before i: MinimalIndex) -> MinimalIndex { + timesPredecessorCalled.value += 1 + return base.index(before: i) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + return base.distance(from: start, to: end) + } + + public func index(_ i: Index, offsetBy n: Int) -> Index { + return base.index(i, offsetBy: n) + } + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + } + + public init() { + base = Base() + } + + public mutating func replaceSubrange( + _ subRange: Range.Index>, + with newElements: C + ) where C : Collection, C.Element == Element { + base.replaceSubrange(subRange, with: newElements) + } +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedRandomAccessRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedRandomAccessRangeReplaceableSlice + public typealias Base = MinimalRangeReplaceableRandomAccessCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedRandomAccessRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedMutableRandomAccessCollection : RandomAccessCollection, MutableCollection { + public typealias Base = MinimalMutableRandomAccessCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + // FIXME: this shouldn't be necessary, should come by default + public typealias Indices = DefaultIndices> + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalMutableRandomAccessCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + public let timesPredecessorCalled = ResettableValue(0) + + public func index(before i: MinimalIndex) -> MinimalIndex { + timesPredecessorCalled.value += 1 + return base.index(before: i) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + return base.distance(from: start, to: end) + } + + public func index(_ i: Index, offsetBy n: Int) -> Index { + return base.index(i, offsetBy: n) + } + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + set { + base[i] = newValue + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + set { + _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) + } + } + +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedRandomAccessRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedRandomAccessRangeReplaceableSlice + public typealias Base = MinimalMutableRandomAccessCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedRandomAccessRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ + + +/// A Collection that uses as many default implementations as +/// `Collection` can provide. +public struct DefaultedMutableRangeReplaceableRandomAccessCollection : RandomAccessCollection, MutableCollection, RangeReplaceableCollection { + public typealias Base = MinimalMutableRangeReplaceableRandomAccessCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + // FIXME: this shouldn't be necessary, should come by default + public typealias Indices = DefaultIndices> + + public var base: Base + + public init(base: Base) { + self.base = base + } + + public init(_ array: [Element]) { + self.base = Base(elements: array) + } + + public init(elements: [Element]) { + self.base = Base(elements: elements) + } + + public init( + elements: S, + underestimatedCount: UnderestimatedCountBehavior = .value(0) + ) where S.Element == Element { + self.init(base: + MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements, underestimatedCount: underestimatedCount)) + } + + public var underestimatedCount: Int { + return base.underestimatedCount + } + + public let timesMakeIteratorCalled = ResettableValue(0) + + public func makeIterator() -> MinimalIterator { + timesMakeIteratorCalled.value += 1 + return base.makeIterator() + } + + + public let timesSuccessorCalled = ResettableValue(0) + + public func index(after i: MinimalIndex) -> MinimalIndex { + timesSuccessorCalled.value += 1 + return base.index(after: i) + } + + public let timesPredecessorCalled = ResettableValue(0) + + public func index(before i: MinimalIndex) -> MinimalIndex { + timesPredecessorCalled.value += 1 + return base.index(before: i) + } + + public func distance(from start: MinimalIndex, to end: MinimalIndex) + -> Int { + return base.distance(from: start, to: end) + } + + public func index(_ i: Index, offsetBy n: Int) -> Index { + return base.index(i, offsetBy: n) + } + + + public let timesStartIndexCalled = ResettableValue(0) + + public var startIndex: MinimalIndex { + timesStartIndexCalled.value += 1 + return base.startIndex + } + + public let timesEndIndexCalled = ResettableValue(0) + + public var endIndex: MinimalIndex { + timesEndIndexCalled.value += 1 + return base.endIndex + } + + public subscript(i: MinimalIndex) -> Element { + get { + return base[i] + } + set { + base[i] = newValue + } + } + + // FIXME: swift-3-indexing-model: use defaults. +// if Self not in ['DefaultedCollection', 'DefaultedBidirectionalCollection', 'DefaultedRandomAccessCollection', 'DefaultedMutableCollection', 'DefaultedRangeReplaceableCollection']: + + public subscript(bounds: Range) -> Slice> { + get { + // FIXME: swift-3-indexing-model: range check. + return Slice(base: self, bounds: bounds) + } + set { + _writeBackMutableSlice(&self, bounds: bounds, slice: newValue) + } + } + + public init() { + base = Base() + } + + public mutating func replaceSubrange( + _ subRange: Range.Index>, + with newElements: C + ) where C : Collection, C.Element == Element { + base.replaceSubrange(subRange, with: newElements) + } +} + +/* +FIXME: swift-3-indexing-model: uncomment this. +public struct DefaultedRandomAccessRangeReplaceableSlice + : RangeReplaceableCollection { + + public typealias Self_ = DefaultedRandomAccessRangeReplaceableSlice + public typealias Base = MinimalMutableRangeReplaceableRandomAccessCollection + public typealias Iterator = MinimalIterator + public typealias Index = MinimalIndex + + public var base: Base + public var startIndex: Index + public var endIndex: Index + + public init() { + expectSliceType(Self_.self) + + self.base = Base() + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base) { + self.base = base + self.startIndex = base.startIndex + self.endIndex = base.endIndex + } + + public init(base: Base, bounds: Range) { + self.base = base + self.startIndex = bounds.lowerBound + self.endIndex = bounds.upperBound + } + + public init(_ array: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: array)) + } + + public init(elements: [Element]) { + self = DefaultedRandomAccessRangeReplaceableSlice( + base: Base(elements: elements)) + } + + public func makeIterator() -> MinimalIterator { + return MinimalIterator(Array(self)) + } + + public subscript(index: Index) -> Element { + Index._failEarlyRangeCheck(index, bounds: startIndex..) -> Self_ { + Index._failEarlyRangeCheck2( + rangeStart: bounds.lowerBound, + rangeEnd: bounds.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + return DefaultedRandomAccessRangeReplaceableSlice( + base: base, bounds: bounds) + } + + public mutating func replaceSubrange< + C : Collection + >( + _ subRange: Range, + with newElements: C + ) where C.Element == Element { + let startOffset = startIndex.position + let endOffset = + endIndex.position + - subRange.count + + numericCast(newElements.count) as Int + Index._failEarlyRangeCheck2( + rangeStart: subRange.lowerBound, + rangeEnd: subRange.upperBound, + boundsStart: startIndex, + boundsEnd: endIndex) + base.replaceSubrange(subRange, with: newElements) + startIndex = base.startIndex.advanced(by: startOffset) + endIndex = base.startIndex.advanced(by: endOffset) + } +} +*/ diff --git a/Tests/PerformanceTest/VisitorPerformanceTests.swift b/Tests/PerformanceTest/VisitorPerformanceTests.swift new file mode 100644 index 00000000000..5e154390f0c --- /dev/null +++ b/Tests/PerformanceTest/VisitorPerformanceTests.swift @@ -0,0 +1,54 @@ +import XCTest +import SwiftSyntax + +public class VisitorPerformanceTests: XCTestCase { + + var inputFile: URL { + return URL(fileURLWithPath: #file) + .deletingLastPathComponent() + .appendingPathComponent("Inputs") + .appendingPathComponent("MinimalCollections.swift.input") + } + + func testEmptyVisitorPerformance() { + class EmptyVisitor: SyntaxVisitor {} + + XCTAssertNoThrow(try { + let parsed = try SyntaxParser.parse(inputFile) + + let emptyVisitor = EmptyVisitor() + + measure { + emptyVisitor.walk(parsed) + } + }()) + } + + func testEmptyRewriterPerformance() { + class EmptyRewriter: SyntaxRewriter {} + + XCTAssertNoThrow(try { + let parsed = try SyntaxParser.parse(inputFile) + + let emptyRewriter = EmptyRewriter() + + measure { + _ = emptyRewriter.visit(parsed) + } + }()) + } + + func testEmptyAnyVistorPerformance() { + class EmptyAnyVisitor: SyntaxAnyVisitor {} + + XCTAssertNoThrow(try { + let parsed = try SyntaxParser.parse(inputFile) + + let emptyVisitor = EmptyAnyVisitor() + + measure { + emptyVisitor.walk(parsed) + } + }()) + } +}