Predicate to compare 2 elements.
The forward range to search.
The forward range to look for.
A sub-type of std.typecons.Tuple of the split portions of haystack (see above for details). This sub-type of Tuple defines opCast!bool, which returns true when the separating needle was found and false otherwise.
Returning a subtype of std.typecons.Tuple enables the following convenient idiom:
// findSplit returns a triplet if (auto split = "dlang-rocks".findSplit("-")) { assert(split[0] == "dlang"); assert(split[1] == "-"); assert(split[2] == "rocks"); } else assert(0); // findSplitBefore returns 2 ranges if (const split = [2, 3, 2, 3, 4, 1].findSplitBefore!"a > b"([2, 2])) { assert(split[0] == [2, 3, 2]); // [3, 4] each greater than [2, 2] assert(split[1] == [3, 4, 1]); } else assert(0);
import std.range.primitives : empty; auto a = "Carl Sagan Memorial Station"; auto r = findSplit(a, "Velikovsky"); import std.typecons : isTuple; static assert(isTuple!(typeof(r.asTuple))); static assert(isTuple!(typeof(r))); assert(!r); assert(r[0] == a); assert(r[1].empty); assert(r[2].empty); r = findSplit(a, " "); assert(r[0] == "Carl"); assert(r[1] == " "); assert(r[2] == "Sagan Memorial Station"); if (const r1 = findSplitBefore(a, "Sagan")) { assert(r1); assert(r1[0] == "Carl "); assert(r1[1] == "Sagan Memorial Station"); } if (const r2 = findSplitAfter(a, "Sagan")) { assert(r2); assert(r2[0] == "Carl Sagan"); assert(r2[1] == " Memorial Station"); }
Use std.range.only to find single elements:
import std.range : only; assert([1, 2, 3, 4].findSplitBefore(only(3))[0] == [1, 2]);
These functions find the first occurrence of needle in haystack and then split haystack as follows.
$(PANEL `findSplit` returns a tuple `result` containing $(I three) ranges. $(UL $(LI `result[0]` is the portion of `haystack` before `needle`) $(LI `result[1]` is the portion of `haystack` that matches `needle`) $(LI `result[2]` is the portion of `haystack` after the match.) ) If `needle` was not found, `result[0]` comprehends `haystack` entirely and `result[1]` and `result[2]` are empty. `findSplitBefore` returns a tuple `result` containing two ranges. $(UL $(LI `result[0]` is the portion of `haystack` before `needle`) $(LI `result[1]` is the balance of `haystack` starting with the match.) ) If `needle` was not found, `result[0]` comprehends `haystack` entirely and `result[1]` is empty. `findSplitAfter` returns a tuple `result` containing two ranges. $(UL $(LI `result[0]` is the portion of `haystack` up to and including the match) $(LI `result[1]` is the balance of `haystack` starting after the match.) ) If `needle` was not found, `result[0]` is empty and `result[1]` is `haystack`. )
In all cases, the concatenation of the returned ranges spans the entire haystack.