<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Mar 10, 2014 at 9:14 PM, Jonathan M Davis <span dir="ltr"><<a href="mailto:jmdavisProg@gmx.com" target="_blank">jmdavisProg@gmx.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5">On Monday, March 10, 2014 21:50:25 Nick Sabalausky wrote:<br>
> On 3/10/2014 9:24 PM, Timothee Cour wrote:<br>
> > Is there a way to do the following lazily:<br>
> ><br>
> > writelnIfNotEmpty(T)(T a){<br>
> > auto b=text(a);<br>
> > if(b.length)<br>
> ><br>
> > writeln(b);<br>
> ><br>
> > }<br>
> ><br>
> > ie, without using std.conv.text (which needlessly computes an intermediate<br>
> > string, which could be quite large) or launching a separate process ?<br>
> ><br>
> > writelnIfNotEmpty(""); //doesn't print new line<br>
> > writelnIfNotEmpty("a"); //prints "a\n"<br>
><br>
> Sounds like what you need is a version of to!string() or text() that<br>
> takes an output sink. Taking a look at std.conv, I'm kinda surprised I<br>
> don't see one :/<br>
<br>
</div></div>std.format.formattedWrite will do the equivalent of writef to an output range,<br>
though I'm not sure that that will really do what the OP wants, since it would<br>
still have to write the result to an output range even if it were empty, and<br>
odds are that the output range would be something on the heap anyway (e.g.<br>
Appender is technically on the stack, but it's contents are on the heap),<br>
making it so that it probably doesn't help much in this case.<br>
<br>
Though to be honest, I'm not quite sure why writelnIfNotEmpty would be very<br>
useful unless what's being passed in would result in the empty string, and I<br>
would think that that would almost always be detectable (the one exception<br>
being user-defined types whose toString results in an empty string). Something<br>
as simple as<br>
<br>
void writelnIfNotEmpty(T)(T a)<br>
{<br>
static if(isInputRange!T)<br>
{<br>
if(!a.empty)<br>
writeln(a);<br>
}<br>
else<br>
writeln(a);<br>
}<br>
<br>
would then cover most cases - the one exception being toStrings which can<br>
result in empty. And if that's a concern, then something like<br>
<br>
else static if(is(T == struct) || is(T == class))<br>
{<br>
auto b = to!string(a);<br>
if(b.length)<br>
writeln(b);<br>
}<br>
<br>
should take care of the toString case. It doesn't avoid creating an<br>
intermediate string, but unless the toString takes an output range, it's<br>
always going to allocate anyway, and if it does take an output range, once<br>
again, you'd need one which somehow avoided allocating altogether, which isn't<br>
particularly likely.<br>
<br>
Alternatively, you could just assume that no toString will result in the empty<br>
string, as it's probably pretty rare that it would, but I'm not sure that that<br>
would actually save you any overhead except in the case where the toString<br>
takes an output range (since otherwise, it'll allocate a new string<br>
regardless), but toStrings which take output ranges are fairly uncommon at<br>
this point.<br>
<span class=""><font color="#888888"><br>
- Jonathan M Davis<br></font></span></blockquote><div><br></div><div><br></div><div>Thanks,</div><div>that indeed works in many cases but there are still others (eg what if empty() prints, say in debug mode: writelnIfNotEmpty would not print the debug information even though writeln() would execute that debug code and print something).</div>
<div><br></div><div>I was wondering whether there would be a robust way that would check whether anything was written to stdout (eg via accessing raw file pointer/C lib), eg something like that :</div><div><br></div><div>
void writelnIfNotEmpty(T)(T a){<br></div><div>auto file_pos=get_filepos(stdin);</div><div>write(a);</div><div>if(get_filepos(stdin)!=file_pos)</div><div>writeln;</div><div>}</div><div><br></div><div><br></div><div> </div>
</div><br></div></div>