Perfect forwarding

Chad Joan chadjoan at gmail.com
Fri Jul 31 09:10:44 UTC 2020


On Wednesday, 29 July 2020 at 20:07:35 UTC, Stefan Koch wrote:
>
> I would be interested an actual use-cases for this?
>
> Where would you use, forward? Where would it be the most 
> pleasant solution, and others would be vastly inferior?

I just ran into a use-case tonight! Maybe. The caveat is that my 
use case might be pretty easy compared to what Andrei is asking 
for. My use case requires modifying the function signature a lot, 
but that can actually be exploited to make my solution easier. I 
probably only need to forward storage class. It's still kinda 
leading to code that feels wrong or isn't obvious, so maybe it 
will help your discussion.

Now for the use-case itself:

I am considering putting a "stringize" method in my types, with a 
signature (by convention) like so:
@nogc nothrow void stringize(return scope StringVacuum writer) { 
... }

(I also plan to support a UFCS-style variant, but let's not get 
distracted.)

This method allows a type to be converted to a string, much like 
with "toString", but without a direct implication of heap-based 
(e.g. GC) memory allocation. If the type's string representation 
is being consumed by a non-memory source, such as stdout or a 
file stream, then it should be *possible* to avoid memory 
allocations entirely, at least in most cases, and with the very 
technical exception of small stack-allocated buffers for handling 
things like integer/float stringization (not shown here).

Gee, it would really suck if this were some kind of departure 
from the norm that caused incompatibilities with existing code 
and infrastructure. Whoops.

But it's OK, because "stringize" is toString-but-better, so it 
should be possible to just mechanically derive a "toString" 
function from every "stringize" function. Whenever this is used, 
it does abandon the original zero-allocation-conversion-to-string 
feature, but "toString" never had that to begin with (at least 
not in the general case; just for static strings and such). Code 
that acknowledges "stringize" can level-up. Code that depends on 
"toString" still works. Cool.

Now it would be really nice if the "toString" method generated 
from a "stringize" method would inherit its compile-time 
guarantees wherever possible. And sometimes it isn't possible. If 
"stringize" is 'nothrow', then "toString" based on "stringize" 
should also be 'nothrow'. However, if "stringize" is 'nogc', this 
does not automatically provide an @nogc "toString", because 
"toString" is required to concatenate a bunch of stringize's text 
fragments, and that concatenation requires GC allocations 
regardless of how @nogc "stringize" may be.

So a minor step in this process is to forward a permutation of 
"stringize" to "toString".

Here is more detailed code:
https://pastebin.com/JGfkkTxz
I am going to be in drafting-mode for a while and I haven't tried 
to compile any of that code. Please expect mistakes; I'm 
providing this to illustrate intent. I hope it helps.


More information about the Digitalmars-d mailing list