Refactored distacen() so that it now accepts the lengths of the ranges
because we already calculate these in levenshteinDistance().
Altered ss in distance() and tt in distanceWithPath().
Moved popFront()’s to after their final usage to handle transitive
ranges.
Corrected path() so that it calls distanceWithPath() instead of
distance().
Moved checks for which Range is longer to levenshteinDistance() method.
Reverted to implementation found in original distance() with regards to
using front/popFront instead of opIndex.
Fixed formatting of return statement.
Added two unit tests for levenshteinDistance().
Credit to @Poita.
Moved to be a private method and only expose new more memory efficient
distance(). This is done because we need the old implementation for
path(). Modified levenshteinDistanceAndPath() to use the old distance()
to reflect this.
Modified the implementation of Levenshtein distance so that it now uses O(n) memory but retains the same time complexity. However, does not work with path().
Modified the implementation of Levenshtein distance so that it now uses O(n) memory but retains the same time complexity. However, does not work with path().
memcpy is not CTFEable, so avoid it for structs without
dtor, postblit that can be assigned with plain =.
This leaves as is (compile error in CTFE) structs that contain
immutable/const memebers the fact that moves overwrites such
fields is questionable to begin with.
Adding extra asserts always helps. As for the enforce, I'm unsure why it was there in the first place: All the other branches simply make the assumption the target is large enough.
Fixing 9975 revealed that checking `pointsTo` was creating problems in swap for legitimate use cases.
This is because:
1. pointsTo can sometimes create "false positives"
2. Internal pointing is not outright forbidden, it is just that the runtime is allowed to make the assumption they don't exist.
While swapping aliasing objects is a sign of stink, it should still "just work".