src/diff32.js
import assert from 'assert';
import {ValueError} from '@failure-abstraction/error';
import longestCommonPrefix from './longestCommonPrefix.js';
import longestCommonSuffix from './longestCommonSuffix.js';
import recurse from './recurse.js';
import recurseDeep from './recurseDeep.js';
/**
* Yields diff rectangles.
* Undefined behavior if indices are not int32.
*
* @param {number} MAX
* @param {Function} eq
* @param {number} li
* @param {number} lj
* @param {number} ri
* @param {number} rj
* @return {IterableIterator}
*/
export default function diff32(MAX, eq, li, lj, ri, rj) {
assert(Number.isInteger(MAX) && MAX >= -2147483648 && MAX <= 2147483647);
assert(Number.isInteger(li) && li >= -2147483648 && li <= 2147483647);
assert(Number.isInteger(lj) && lj >= -2147483648 && lj <= 2147483647);
assert(Number.isInteger(ri) && ri >= -2147483648 && ri <= 2147483647);
assert(Number.isInteger(rj) && rj >= -2147483648 && rj <= 2147483647);
const N = (lj - li) | 0;
const M = (rj - ri) | 0;
assert(MAX <= N + M);
if (MAX < 0) throw new ValueError();
if (MAX === 0 && N !== M) throw new ValueError();
const l0 = longestCommonPrefix(eq, li, lj, ri, rj);
if (l0 === lj && N === M) return [][Symbol.iterator]();
if (MAX === 0) throw new ValueError();
const r0 = (ri + ((l0 - li) | 0)) | 0;
const l1 = longestCommonSuffix(eq, lj, l0, rj, r0);
const r1 = (rj - ((lj - l1) | 0)) | 0;
assert(l0 < l1 || r0 < r1);
return MAX < ((((l1 - l0) | 0) + ((r1 - r0) | 0)) | 0)
? recurse(MAX, eq, l0, l1, r0, r1)
: recurseDeep((((l1 - l0) | 0) + ((r1 - r0) | 0)) | 0, eq, l0, l1, r0, r1);
}