1 module nxt.string_ex; 2 3 public import nxt.sso_string; 4 public import nxt.packed_string; 5 6 /** Call `dg` with `src` as input. 7 * 8 * See_Also: https://youtu.be/V6KFtzF2Hx8 9 */ 10 auto toCStringThen(alias dg, uint smallSize = 512)(const(char)[] src) 11 if (is(typeof(dg((char[]).init)))) /+ TODO: assert that dg takes its parameter by scope +/ 12 { 13 import core.memory : pureMalloc, pureFree; 14 const srcLength = src.length + 1; 15 char[smallSize] stackBuf = void; 16 17 const useHeap = srcLength > stackBuf.length; 18 scope char* ptr; 19 () @trusted { 20 if (useHeap) 21 ptr = cast(typeof(ptr))pureMalloc(src.length + 1); 22 else 23 ptr = stackBuf.ptr; 24 ptr[0 .. src.length] = src[]; 25 ptr[src.length] = '\0'; 26 } (); 27 scope(exit) 28 if (useHeap) 29 () @trusted { pureFree(ptr); } (); 30 31 scope char[] buf; 32 () @trusted { 33 buf = ptr[0 .. srcLength]; 34 } (); 35 36 return dg(buf); 37 } 38 39 /// 40 pure nothrow @safe @nogc unittest { 41 enum smallSize = 4; 42 const src = "42"; 43 scope char[src.length + 1] y; 44 @safe void f(in char[] x) { y = x; } 45 src.toCStringThen!(f, smallSize)(); // uses stack 46 assert(y[0 .. $ - 1] == src); 47 assert(y[$ - 1 .. $] == "\0"); 48 } 49 50 /// 51 pure nothrow @safe @nogc unittest { 52 enum smallSize = 4; 53 const src = "4200"; 54 scope char[src.length + 1] y; 55 @safe void f(in char[] x) { y = x; } 56 src.toCStringThen!(f, smallSize)(); // uses heap 57 assert(y[0 .. $ - 1] == src); 58 assert(y[$ - 1 .. $] == "\0"); 59 } 60 61 /** Zero-Terminated string. 62 See: https://discord.com/channels/242094594181955585/625407836473524246/1018276401142575188 63 */ 64 struct Stringz 65 { 66 this(string s) pure nothrow @safe @nogc 67 in (s.length >= 1 && 68 s[$ - 1] == '\0') 69 { 70 _data = s[0 .. $ - 1]; 71 } 72 string toString() const @property pure nothrow @safe @nogc { return _data; } 73 private string _data; 74 } 75 76 enum stringz(string literal) = () { 77 Stringz result; 78 result._data = literal; // ok - literals are 0-terminated 79 return result; 80 }(); 81 82 /// 83 pure @safe unittest { 84 enum _ = stringz!("42"); 85 assert(_.toString == "42"); 86 }