cartesianProduct improvement

Partial fix for issues:
https://issues.dlang.org/show_bug.cgi?id=9878
https://issues.dlang.org/show_bug.cgi?id=10693
https://issues.dlang.org/show_bug.cgi?id=10779
https://issues.dlang.org/show_bug.cgi?id=12957

The full fix is a little complex, so I thought at least the partial fix should go in first. Basically, this PR includes two fixes: standardize on lexicographic output order (for now), and for finite forward ranges, use a much less template-heavy implementation that doesn't involve an exponential number of template instantiations. For infinite ranges and non-forward ranges, we fall back to the old implementation, but I think the finite forward range case is probably the most common, and benefits the most from this fix, so it should be merged now rather than later.