Intersect two ranges in Swift Can you think of a reason the following extension should not be used in production, or a better way of implementing it:

public extension Range {

    @warn_unused_result
    public func intersect(other: Range) -&gt; Range {

        let ds = startIndex.distanceTo(other.startIndex)
        let de = startIndex.distanceTo(other.endIndex)

        let s = ds &lt;= 0 ? startIndex : startIndex.advancedBy(ds, limit: endIndex)
        let e = de &lt;= 0 ? startIndex : startIndex.advancedBy(de, limit: endIndex)

        return s..&lt;e
    }
}


The method should pass the following assertions:

(5...7).intersect(9...9) == (8..&lt;8) // ....|||.---..
(5...7).intersect(1...3) == (5..&lt;5) // ....---.|||..

(5...7).intersect(8...9) == (8..&lt;8) // ....|||---...
(5...7).intersect(1...4) == (5..&lt;5) // ....---|||...

(5...7).intersect(7...9) == (7..&lt;8) // ....||+--....
(5...7).intersect(1...5) == (5..&lt;6) // ....--+||....

(5...7).intersect(6...9) == (6..&lt;8) // ....|++-.....
(5...7).intersect(1...6) == (5..&lt;7) // ....-++|.....

(5...7).intersect(6...6) == (6..&lt;7) // ....|+|......
(5...7).intersect(4...8) == (5..&lt;8) // ....-+++-....


Note the first four assertions with an empty intersection: the method is currently returning startIndex..&lt;startIndex if the other range is on the "left", or endIndex..&lt;endIndex if it is on the "right". Is this a reasonable behaviour?
There is a general problem: The 
distanceTo(_: Self) -&gt; Self.Distance of the
ForwardIndexType protocol requires that


  
  start and end are part of the same sequence when conforming to RandomAccessSequenceType.
  end is reachable from self by incrementation otherwise.
  


(and RandomAccessSequenceType is probably a typo and should be
RandomAccessIndexType).

Here is a simple example where this conditions are not met, and
your code crashes:

let r1 = "foo".rangeOfString("")!
print(r1) // 1..&lt;5
let r2 = "bar".rangeOfString("")!
print(r2) // 2..&lt;6
let r = r1.intersect(r2) // fatal error: cannot increment endIndex


Incrementing the start index of r1 never hits the start index
of r2.

Here is another example:

struct MyIndex: ForwardIndexType {
    let value: Int

    func successor() -&gt; MyIndex {
        return MyIndex(value: self.value + 1)
    }
}

func == (lhs: MyIndex, rhs: MyIndex) -&gt; Bool {
    return lhs.value == rhs.value
}


is an index which can only be incremented. Then

let r1 = Range(MyIndex(value: 4) ... MyIndex(value: 6))
let r2 = Range(MyIndex(value: 3) ... MyIndex(value: 5))
let r = r1.intersect(r2)


will loop forever, because incrementing MyIndex(value: 4) 
never reaches MyIndex(value: 3).

So intersecting ranges makes only sense if both ranges refer
to the same sequence. I don't know if that can be ensured at 
compile time with a suitable restriction, I assume that it is 
not possible. It should at least be documented (similar to the
above mentioned requirements of ForwardIndexType).

You could restrict the method to ranges of integer elements

public extension Range where Element : IntegerType { ... }


but of course that reduces its usability considerably.

The implementation itself looks good to me. The behavior in the case
of an empty intersection it a sensible choice. Is similar to that of the clamp() 
method of ClosedInterval:

ClosedInterval(3, 4).clamp(ClosedInterval(5, 6)) // 4 ... 4
ClosedInterval(3, 4).clamp(ClosedInterval(1, 2)) // 3 ... 3


which returns the left or right bound, depending on wether the other
interval lies on the left or on the right.

If your ranges just represent intervals and do not refer to indices
of sequences, then ClosedInterval (and the existing clamp() method) might be an alternative.