I think the general idea seems useful, but the proposed versions seem kind of hard to use due to the 3-tuple return combined with optional types. The usage examples you give mostly just test these for optionality, and they all ignore the prefix count. I also notice that the C++ version returns the pair of iterators, making it easier to pick up from where you left off, a use case that you might want to consider. In general I would be interested in seeing more use cases and alternative implementations.
I don't have time right now to think a lot about this, but one possibility would be something like
zip(_:_:), returning a (lazy?) sequence type that provided this information in some form. e.g. return a sequence of enum cases roughly like
.secondSuffix(S2.SubSequence), but with better names and more thought about the performance requirements and details (e.g. should
.notEqual provide elements or equal length subsequences where they differ?).
divergence([2, 3, 4, 5], [2, 3, 5, 7, 11])
// roughly [.equal([2, 3]), .notEqual(4, 5), .notEqual(5, 7), .secondSuffix()]
// or [.equal([2, 3]), .notEqual([4, 5], [5, 7]), .secondSuffix()]
Or if that is too general and almost all the use cases really only need the length of the common prefix and the differing elements, you could consider returning a struct with the common prefix length and an enum with a case containing the differing pair of (non-optional) elements and other cases describing the other possibilities (sequences are the same, hit the end of one sequence or the other).