@@ -1615,6 +1615,167 @@ public struct MinimalBidirectionalCollection<T> : BidirectionalCollection {
1615
1615
internal let _collectionState : _CollectionState
1616
1616
}
1617
1617
1618
+ /// A minimal implementation of `Collection` with extra checks.
1619
+ public struct MinimalBidirectionalRandomAccessCollection < T> : BidirectionalCollection , RandomAccessCollection {
1620
+ /// Creates a collection with given contents, but a unique modification
1621
+ /// history. No other instance has the same modification history.
1622
+ public init < S : Sequence > (
1623
+ elements: S ,
1624
+ underestimatedCount: UnderestimatedCountBehavior = . value( 0 )
1625
+ ) where S. Element == T {
1626
+ self . _elements = Array ( elements)
1627
+
1628
+ self . _collectionState = _CollectionState (
1629
+ newRootStateForElementCount: self . _elements. count)
1630
+
1631
+ switch underestimatedCount {
1632
+ case . precise:
1633
+ self . underestimatedCount = _elements. count
1634
+
1635
+ case . half:
1636
+ self . underestimatedCount = _elements. count / 2
1637
+
1638
+ case . overestimate:
1639
+ self . underestimatedCount = _elements. count * 3 + 5
1640
+
1641
+ case . value( let count) :
1642
+ self . underestimatedCount = count
1643
+ }
1644
+ }
1645
+
1646
+
1647
+ public let timesMakeIteratorCalled = ResettableValue ( 0 )
1648
+
1649
+ public func makeIterator( ) -> MinimalIterator < T > {
1650
+ timesMakeIteratorCalled. value += 1
1651
+ return MinimalIterator ( _elements)
1652
+ }
1653
+
1654
+ public typealias Index = MinimalIndex
1655
+
1656
+ internal func _index( forPosition i: Int ) -> MinimalIndex {
1657
+ return MinimalIndex (
1658
+ collectionState: _collectionState,
1659
+ position: i,
1660
+ startIndex: _elements. startIndex,
1661
+ endIndex: _elements. endIndex)
1662
+ }
1663
+
1664
+ internal func _uncheckedIndex( forPosition i: Int ) -> MinimalIndex {
1665
+ return MinimalIndex (
1666
+ _collectionState: _collectionState,
1667
+ uncheckedPosition: i)
1668
+ }
1669
+
1670
+ public let timesStartIndexCalled = ResettableValue ( 0 )
1671
+
1672
+ public var startIndex : MinimalIndex {
1673
+ timesStartIndexCalled. value += 1
1674
+ return _uncheckedIndex ( forPosition: _elements. startIndex)
1675
+ }
1676
+
1677
+ public let timesEndIndexCalled = ResettableValue ( 0 )
1678
+
1679
+ public var endIndex : MinimalIndex {
1680
+ timesEndIndexCalled. value += 1
1681
+ return _uncheckedIndex ( forPosition: _elements. endIndex)
1682
+ }
1683
+
1684
+
1685
+ public func _failEarlyRangeCheck(
1686
+ _ index: MinimalIndex ,
1687
+ bounds: Range < MinimalIndex >
1688
+ ) {
1689
+ _expectCompatibleIndices (
1690
+ _uncheckedIndex ( forPosition: index. position) ,
1691
+ index)
1692
+
1693
+ _expectCompatibleIndices (
1694
+ _uncheckedIndex ( forPosition: bounds. lowerBound. position) ,
1695
+ bounds. lowerBound)
1696
+ _expectCompatibleIndices (
1697
+ _uncheckedIndex ( forPosition: bounds. upperBound. position) ,
1698
+ bounds. upperBound)
1699
+
1700
+ expectTrapping (
1701
+ index. position,
1702
+ in: bounds. lowerBound. position..< bounds. upperBound. position)
1703
+ }
1704
+
1705
+ public func _failEarlyRangeCheck(
1706
+ _ range: Range < MinimalIndex > ,
1707
+ bounds: Range < MinimalIndex >
1708
+ ) {
1709
+ _expectCompatibleIndices (
1710
+ _uncheckedIndex ( forPosition: range. lowerBound. position) ,
1711
+ range. lowerBound)
1712
+ _expectCompatibleIndices (
1713
+ _uncheckedIndex ( forPosition: range. upperBound. position) ,
1714
+ range. upperBound)
1715
+
1716
+ _expectCompatibleIndices (
1717
+ _uncheckedIndex ( forPosition: bounds. lowerBound. position) ,
1718
+ bounds. lowerBound)
1719
+ _expectCompatibleIndices (
1720
+ _uncheckedIndex ( forPosition: bounds. upperBound. position) ,
1721
+ bounds. upperBound)
1722
+
1723
+ expectTrapping (
1724
+ range. lowerBound. position..< range. upperBound. position,
1725
+ in: bounds. lowerBound. position..< bounds. upperBound. position)
1726
+ }
1727
+
1728
+ public func index( after i: MinimalIndex ) -> MinimalIndex {
1729
+ _failEarlyRangeCheck ( i, bounds: startIndex..< endIndex)
1730
+ return _uncheckedIndex ( forPosition: i. position + 1 )
1731
+ }
1732
+
1733
+ public func index( before i: MinimalIndex ) -> MinimalIndex {
1734
+ // FIXME: swift-3-indexing-model: perform a range check and use
1735
+ // return _uncheckedIndex(forPosition: i.position - 1)
1736
+ return _index ( forPosition: i. position - 1 )
1737
+ }
1738
+
1739
+ public func distance( from start: MinimalIndex , to end: MinimalIndex )
1740
+ -> Int {
1741
+ // FIXME: swift-3-indexing-model: perform a range check properly.
1742
+ if start != endIndex {
1743
+ _failEarlyRangeCheck ( start, bounds: startIndex..< endIndex)
1744
+ }
1745
+ if end != endIndex {
1746
+ _failEarlyRangeCheck ( end, bounds: startIndex..< endIndex)
1747
+ }
1748
+ return end. position - start. position
1749
+ }
1750
+
1751
+ public func index( _ i: Index , offsetBy n: Int ) -> Index {
1752
+ // FIXME: swift-3-indexing-model: perform a range check properly.
1753
+ if i != endIndex {
1754
+ _failEarlyRangeCheck ( i, bounds: startIndex..< endIndex)
1755
+ }
1756
+ return _index ( forPosition: i. position + n)
1757
+ }
1758
+
1759
+ public subscript( i: MinimalIndex ) -> T {
1760
+ get {
1761
+ _failEarlyRangeCheck ( i, bounds: startIndex..< endIndex)
1762
+ return _elements [ i. position]
1763
+ }
1764
+ }
1765
+
1766
+ public subscript( bounds: Range < MinimalIndex > ) -> Slice < MinimalBidirectionalRandomAccessCollection < T > > {
1767
+ get {
1768
+ _failEarlyRangeCheck ( bounds, bounds: startIndex..< endIndex)
1769
+ return Slice ( base: self , bounds: bounds)
1770
+ }
1771
+ }
1772
+
1773
+
1774
+ public var underestimatedCount : Int
1775
+
1776
+ internal var _elements : [ T ]
1777
+ internal let _collectionState : _CollectionState
1778
+ }
1618
1779
1619
1780
/// A minimal implementation of `Collection` with extra checks.
1620
1781
public struct MinimalRangeReplaceableBidirectionalCollection < T> : BidirectionalCollection , RangeReplaceableCollection {
0 commit comments