File tree Expand file tree Collapse file tree 3 files changed +81
-3
lines changed Expand file tree Collapse file tree 3 files changed +81
-3
lines changed Original file line number Diff line number Diff line change @@ -2607,6 +2607,48 @@ public func < (
26072607 return MinimalComparableValue . lessImpl. value ( lhs. value, rhs. value)
26082608}
26092609
2610+ /// A type that conforms only to `Comparable` and `ForwardIndexType`.
2611+ ///
2612+ /// This type can be used to check that generic functions don't rely on any
2613+ /// other conformances.
2614+ public struct MinimalComparableIndexValue : Comparable , ForwardIndexType {
2615+ public static var timesEqualEqualWasCalled = 0
2616+ public static var timesLessWasCalled = 0
2617+
2618+ public func successor( ) -> MinimalComparableIndexValue {
2619+ return MinimalComparableIndexValue ( value. successor ( ) )
2620+ }
2621+
2622+ public var value : Int
2623+ public var identity : Int
2624+
2625+ public init ( _ value: Int ) {
2626+ self . value = value
2627+ self . identity = 0
2628+ }
2629+
2630+ public init ( _ value: Int , identity: Int ) {
2631+ self . value = value
2632+ self . identity = identity
2633+ }
2634+ }
2635+
2636+ public func == (
2637+ lhs: MinimalComparableIndexValue ,
2638+ rhs: MinimalComparableIndexValue
2639+ ) -> Bool {
2640+ MinimalComparableIndexValue . timesEqualEqualWasCalled += 1
2641+ return lhs. value == rhs. value
2642+ }
2643+
2644+ public func < (
2645+ lhs: MinimalComparableIndexValue ,
2646+ rhs: MinimalComparableIndexValue
2647+ ) -> Bool {
2648+ MinimalComparableIndexValue . timesLessWasCalled += 1
2649+ return lhs. value < rhs. value
2650+ }
2651+
26102652// ${'Local Variables'}:
26112653// eval: (read-only-mode 1)
26122654// End:
Original file line number Diff line number Diff line change @@ -153,6 +153,29 @@ extension Range : CustomReflectable {
153153 }
154154}
155155
156+ /// O(1) implementation of `contains()` for ranges of comparable elements.
157+ extension Range where Element: Comparable {
158+ @warn_unused_result
159+ func _customContainsEquatableElement( element: Generator . Element ) -> Bool ? {
160+ return element >= self . startIndex && element < self . endIndex
161+ }
162+
163+ // FIXME: copied from SequenceAlgorithms as a workaround for https://bugs.swift.org/browse/SR-435
164+ @warn_unused_result
165+ public func contains( element: Generator . Element ) -> Bool {
166+ if let result = _customContainsEquatableElement ( element) {
167+ return result
168+ }
169+
170+ for e in self {
171+ if e == element {
172+ return true
173+ }
174+ }
175+ return false
176+ }
177+ }
178+
156179@warn_unused_result
157180public func == < Element> ( lhs: Range < Element > , rhs: Range < Element > ) -> Bool {
158181 return lhs. startIndex == rhs. startIndex &&
@@ -207,8 +230,6 @@ public func ... <Pos : ForwardIndexType where Pos : Comparable> (
207230public func ~= < I : ForwardIndexType where I : Comparable > (
208231 pattern: Range < I > , value: I
209232) -> Bool {
210- // Intervals can check for containment in O(1).
211- return
212- HalfOpenInterval ( pattern. startIndex, pattern. endIndex) . contains ( value)
233+ return pattern. contains ( value)
213234}
214235
Original file line number Diff line number Diff line change @@ -608,6 +608,21 @@ SequenceTypeTests.test("Set<T>.contains/CustomImplementation/${dispatch}") {
608608
609609% end
610610
611+ SequenceTypeTests . test ( " Range<Element>.contains/WhereElementIsComparable/dispatch " ) {
612+ MinimalComparableIndexValue . timesLessWasCalled = 0
613+ let start = 0
614+ let end = 10
615+ let range = Range ( start: MinimalComparableIndexValue ( start) , end: MinimalComparableIndexValue ( end) )
616+ let count = 20
617+ for test in 0 ..< count {
618+ expectEqual (
619+ test >= start && test < end,
620+ range. contains ( MinimalComparableIndexValue ( test) ) )
621+ }
622+ expectEqual (
623+ count * 2 , MinimalComparableIndexValue . timesLessWasCalled)
624+ }
625+
611626SequenceTypeTests . test ( " contains/Predicate " ) {
612627 for test in findTests {
613628 let s = MinimalSequence < OpaqueValue < Int > > (
You can’t perform that action at this time.
0 commit comments