1 /++ Algorithms that either improve or complement std.algorithm.mutation.` 2 +/ 3 module nxt.algorithm.mutation; 4 5 /** Array-specialization of `stripLeft` with default predicate. 6 * 7 * See_Also: https://forum.dlang.org/post/dhxwgtaubzbmjaqjmnmq@forum.dlang.org 8 */ 9 inout(T)[] stripLeft(T)(scope return inout(T)[] haystack, scope const T needle) @trusted { 10 static if (is(T : const(char))) 11 assert(needle < 128); // See_Also: https://forum.dlang.org/post/sjirukypxmmcgdmqbcpe@forum.dlang.org 12 size_t offset = 0; 13 while (offset != haystack.length && 14 haystack.ptr[offset] == needle) /+ TODO: elide range-check +/ 15 offset += 1; 16 return haystack.ptr[offset .. haystack.length]; 17 } 18 /// ditto 19 inout(char)[] stripLeft()(scope return inout(char)[] haystack) pure nothrow @safe @nogc /*tlm*/ { 20 return haystack.stripLeft(' '); 21 } 22 /// 23 pure nothrow @safe @nogc unittest { 24 assert("beta".stripLeft(' ') == "beta"); 25 assert(" beta".stripLeft(' ') == "beta"); 26 assert(" beta".stripLeft(' ') == "beta"); 27 assert(" beta".stripLeft(' ') == "beta"); 28 assert(" beta".stripLeft() == "beta"); 29 assert(" _ beta _ ".stripLeft(' ') == "_ beta _ "); 30 assert(" _ beta _ ".stripLeft(' ') == "_ beta _ "); 31 version (unittest) { 32 static char[] f()() @safe pure nothrow { char[1] x = "_"; return x[].stripLeft(' '); } 33 static if (hasPreviewDIP1000) static assert(!__traits(compiles, { auto _ = f(); })); 34 } 35 } 36 37 /** Array-specialization of `stripRight` with default predicate. 38 * 39 * See_Also: https://forum.dlang.org/post/dhxwgtaubzbmjaqjmnmq@forum.dlang.org 40 */ 41 inout(T)[] stripRight(T)(scope return inout(T)[] haystack, scope const T needle) @trusted { 42 static if (is(T : const(char))) 43 assert(needle < 128); // See_Also: https://forum.dlang.org/post/sjirukypxmmcgdmqbcpe@forum.dlang.org 44 size_t offset = haystack.length; 45 while (offset != 0 && 46 haystack.ptr[offset - 1] == needle) /+ TODO: elide range-check +/ 47 offset -= 1; 48 return haystack.ptr[0 .. offset]; 49 } 50 /// ditto 51 inout(T)[] stripRight(T)(scope return inout(T)[] haystack, scope const T[] needles) @trusted { 52 import nxt.algorithm.searching : canFind; 53 static if (is(T : const(char))) 54 foreach (needle; needles) 55 assert(needle < 128); // See_Also: https://forum.dlang.org/post/sjirukypxmmcgdmqbcpe@forum.dlang.org 56 size_t offset = haystack.length; 57 while (offset != 0 && 58 needles.canFind(haystack.ptr[offset - 1])) /+ TODO: elide range-check +/ 59 offset -= 1; 60 return haystack.ptr[0 .. offset]; 61 } 62 /// ditto 63 inout(char)[] stripRight()(scope return inout(char)[] haystack) pure nothrow @safe @nogc /*tlm*/ { 64 return haystack.stripRight([' ', '\t', '\r', '\n']); /+ TODO: `std.ascii.iswhite` instead +/ 65 } 66 /// 67 pure nothrow @safe @nogc unittest { 68 assert("beta".stripRight(' ') == "beta"); 69 assert("beta ".stripRight(' ') == "beta"); 70 assert("beta ".stripRight(' ') == "beta"); 71 assert("beta ".stripRight(' ') == "beta"); 72 assert("beta ".stripRight() == "beta"); 73 assert(" _ beta _ ".stripRight(' ') == " _ beta _"); 74 assert(" _ beta _ ".stripRight(' ') == " _ beta _"); 75 version (unittest) { 76 static char[] f()() @safe pure nothrow { char[1] x = "_"; return x[].stripRight(' '); } 77 static if (hasPreviewDIP1000) static assert(!__traits(compiles, { auto _ = f(); })); 78 } 79 } 80 81 /** Array-specialization of `strip` with default predicate. 82 * 83 * See_Also: https://forum.dlang.org/post/dhxwgtaubzbmjaqjmnmq@forum.dlang.org 84 */ 85 inout(T)[] strip(T)(scope return inout(T)[] haystack, scope const T needle) @trusted { 86 static if (is(T : const(char))) 87 assert(needle < 128); // See_Also: https://forum.dlang.org/post/sjirukypxmmcgdmqbcpe@forum.dlang.org 88 size_t leftOffset = 0; 89 while (leftOffset != haystack.length && 90 haystack.ptr[leftOffset] == needle) /+ TODO: elide range-check +/ 91 leftOffset += 1; 92 size_t rightOffset = haystack.length; 93 while (rightOffset != leftOffset && 94 haystack.ptr[rightOffset - 1] == needle) /+ TODO: elide range-check +/ 95 rightOffset -= 1; 96 return haystack.ptr[leftOffset .. rightOffset]; 97 } 98 /// ditto 99 inout(char)[] strip()(scope return inout(char)[] haystack) pure nothrow @safe @nogc /*tlm*/ { 100 return haystack.strip(' '); 101 } 102 /// 103 pure nothrow @safe @nogc unittest { 104 assert("beta".strip(' ') == "beta"); 105 assert(" beta ".strip(' ') == "beta"); 106 assert(" beta ".strip(' ') == "beta"); 107 assert(" beta ".strip(' ') == "beta"); 108 assert(" _ beta _ ".strip(' ') == "_ beta _"); 109 assert(" _ beta _ ".strip(' ') == "_ beta _"); 110 version (unittest) { 111 static char[] f()() @safe pure nothrow { char[1] x = "_"; return x[].strip(' '); } 112 static if (hasPreviewDIP1000) static assert(!__traits(compiles, { auto _ = f(); })); 113 } 114 } 115 /// 116 pure nothrow @safe @nogc unittest { 117 const ubyte[3] x = [0, 42, 0]; 118 assert(x.strip(0) == x[1 .. 2]); 119 } 120 121 version (unittest) { 122 import nxt.dip_traits : hasPreviewDIP1000; 123 }