empty case
import std.typecons : Nullable; alias T = Nullable!int; immutable length = 0; immutable hitKey = T(42); // key to store auto haystack = new T[length]; assert(haystack.triangularProbeFromIndex!((T element) => (element is hitKey || element.isNull))(0) == haystack.length); assert(haystack.triangularProbeFromIndex!((size_t index, T element) => true)(0) == 0); assert(haystack.triangularProbeFromIndex!((size_t index, T element) => false)(0) == haystack.length);
generic case
import std.typecons : Nullable; alias T = Nullable!int; foreach (immutable lengthPower; 0 .. 20) { immutable length = 2^^lengthPower; immutable hitKey = T(42); // key to store immutable missKey = T(43); // other key not present auto haystack = new T[length]; haystack[] = T(17); // make haystack full haystack[$/2] = hitKey; alias elementHitPredicate = element => (element is hitKey || element.isNull); alias elementMissPredicate = element => (element is missKey || element.isNull); // key hit assert(haystack.triangularProbeFromIndex!(elementHitPredicate)(lengthPower) != haystack.length); // key miss assert(haystack.triangularProbeFromIndex!(elementMissPredicate)(lengthPower) == haystack.length); }