module pattern.repeats; import pattern.base; import std.algorithm; import std.array; import std.conv; import std.range; template repeat(alias pattern) if(__traits(compiles, asPattern!pattern)) { enum repeat = function string(string input) { return std.range.repeat(0) .map!(iterator => asPattern!pattern(input)) .tee!(result => input = input[result.length .. $]) .until!(result => result is null) .joiner .text; }; } version(unittest) { import pattern.brackets; import pattern.optionals; import pattern.primitives; import std.ascii; } unittest { enum r = repeat!(primitive!("a", "b", "c")); assert(r("aabbccdd") == "aabbcc"); assert(r("acbadeac") == "acba"); assert(r("dfeafsdc") is null); } unittest { enum r = repeat!isAlpha; assert(r("abcdef") == "abcdef"); assert(r("ab d f") == "ab"); assert(r("abzd01") == "abzd"); }