1 /// Module to replace std.stdio write functions to @nogc ones 2 module mutils.stdio; 3 4 import core.stdc.stdio: printf, fwrite, stdout; 5 6 import std.meta: aliasSeqOf; 7 import std.traits; 8 9 import mutils.conv; 10 11 static char[1024] gTmpStdioStrBuff;// Own buffer to be independant from mutils.conv 12 13 /** 14 * Writes string to stdout 15 * Compared to std.stdio.writeln this writeln is not using GC, can print @disable this() structs, can print core.simd.vector's 16 * write is not pure but we will pretend it is to enable write debug 17 **/ 18 void write(T...)(auto ref const T el) @trusted { 19 static void writeImpl(EL)(auto ref const EL el){ 20 string elStr=to!(string)(el, gTmpStdioStrBuff[]); 21 fwrite(elStr.ptr, 1, elStr.length, stdout); 22 } 23 24 static auto assumePure(DG)(scope DG t) 25 if (isFunctionPointer!DG || isDelegate!DG) 26 { 27 enum attrs = functionAttributes!DG | FunctionAttribute.pure_; 28 return cast(SetFunctionAttributes!(DG, functionLinkage!DG, attrs)) t; 29 } 30 assumePure( () => writeImpl(el[0]) )(); 31 static if(T.length>1){ 32 write(el[1..$]); 33 } 34 } 35 36 /// Like write but adds new line at end 37 void writeln(T...)(auto ref const T el) { 38 write(el, "\n"); 39 } 40 41 /// Like writeln but adds space beetwen arguments 42 void writelns(T...)(auto ref const T el) { 43 foreach(e; el){ 44 write(e, ' '); 45 } 46 write("\n"); 47 } 48 49 /// Writes format to stdout changing %s to proper argument 50 /// Only %s is supported, it is not printf 51 void writefln(T...)(string format, auto ref const T el) { 52 alias indices=aliasSeqOf!([0,1,2,3,4,5,6,7,8,9,10,123]); 53 int lastEnd=0; 54 int elementsWritten=0; 55 for(int i=0; i<format.length; i++){ 56 char c=format[i]; 57 if(c!='%'){ 58 continue; 59 } 60 assert(format[i+1]=='s');// Only %s is supported 61 write(format[lastEnd..i]); 62 lastEnd=i+2; 63 sw:switch(elementsWritten){ 64 foreach(elNum; indices[0..el.length]){ 65 case elNum: 66 write(el[elNum]); 67 break sw; 68 } 69 default: 70 assert(0, "Wrong number of specifiers and parameters"); 71 } 72 73 elementsWritten++; 74 75 } 76 write("\n"); 77 } 78 79 80 81 private struct TestStruct{ 82 @nogc nothrow @safe pure: 83 @disable this(); 84 @disable this(this); 85 86 this(int i){} 87 int a; 88 double c; 89 } 90 91 // Function because we dont want to prit something during tests 92 private void testMutilsStdio() @nogc nothrow @safe pure{ 93 TestStruct w=TestStruct(3); 94 write("__text__ "); 95 writeln(w, " <- this is struct"); 96 // arrays 97 int[9] arr=[1,2,3,4,5,6,7,8,9]; 98 writeln(arr[]); 99 writeln(arr); 100 // simd 101 import core.simd; 102 ubyte16 vec=14; 103 writeln(vec); 104 // writeln spaced 105 writelns(1,2,3,4,5,6,7,8,9); 106 // writefln 107 writefln("%s <- this is something | and this is something -> %s", w, 1); 108 // writeln empty 109 writeln(); 110 } 111 112 unittest{ 113 //testMutilsStdio(); 114 } 115