Predicate to use for comparing needle against haystack.
The range to search.
What to look for.
A sub-type of Tuple!() of the split portions of haystack (see above for details). This sub-type of Tuple!() has opCast defined for bool. This opCast returns true when the separating needle was found and false otherwise.
Returning a subtype of std.typecons.Tuple enables the following convenient idiom:
1 // findSplit returns a triplet 2 if (auto split = "dlang-rocks".findSplit("-")) 3 { 4 assert(split[0] == "dlang"); 5 assert(split[1] == "-"); 6 assert(split[2] == "rocks"); 7 } 8 else assert(0); 9 10 // works with const aswell 11 if (const split = "dlang-rocks".findSplit("-")) 12 { 13 assert(split[0] == "dlang"); 14 assert(split[1] == "-"); 15 assert(split[2] == "rocks"); 16 } 17 else assert(0);
1 import std.range.primitives : empty; 2 3 auto a = "Carl Sagan Memorial Station"; 4 auto r = findSplit(a, "Velikovsky"); 5 import std.typecons : isTuple; 6 static assert(isTuple!(typeof(r.asTuple))); 7 static assert(isTuple!(typeof(r))); 8 assert(!r); 9 assert(r[0] == a); 10 assert(r[1].empty); 11 assert(r[2].empty); 12 r = findSplit(a, " "); 13 assert(r[0] == "Carl"); 14 assert(r[1] == " "); 15 assert(r[2] == "Sagan Memorial Station"); 16 if (const r1 = findSplitBefore(a, "Sagan")) 17 { 18 assert(r1); 19 assert(r1[0] == "Carl "); 20 assert(r1[1] == "Sagan Memorial Station"); 21 } 22 if (const r2 = findSplitAfter(a, "Sagan")) 23 { 24 assert(r2); 25 assert(r2[0] == "Carl Sagan"); 26 assert(r2[1] == " Memorial Station"); 27 }
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.
findSplit returns a tuple result containing three ranges. result[0] is the portion of haystack before needle, result[1] is the portion of haystack that matches needle, and 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. result[0] is the portion of haystack before needle, and 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. result[0] is the portion of haystack up to and including the match, and 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.
If haystack is a random-access range, all three components of the tuple have the same type as haystack. Otherwise, haystack must be a forward range and the type of result[0] and result[1] is the same as std.range.takeExactly.