Formatted read consumes input

Steven Schveighoffer schveiguy at yahoo.com
Fri Sep 7 11:15:21 PDT 2012


On Fri, 07 Sep 2012 11:34:28 -0400, monarch_dodra <monarchdodra at gmail.com>  
wrote:

> On Friday, 7 September 2012 at 14:51:45 UTC, Steven Schveighoffer wrote:
>> On Fri, 07 Sep 2012 10:35:37 -0400, monarch_dodra
>>
>> This looks ugly.  Returning a tuple and having to split the result is  
>> horrible, I hated dealing with that in C++ (and I even wrote stuff that  
>> returned pairs!)
>>
>> Not only that, but there are possible ranges which may not be  
>> reassignable.
>>
>> I'd rather have a way to wrap a string into a ref-based input range.
>>
>> We have three situations:
>>
>> 1. input range is a ref type already (i.e. a class or a pImpl struct),  
>> no need to pass this by ref, just wastes cycles doing double  
>> dereference.
>> 2. input range is a value type, and you want to preserve the original.
>> 3. input range is a value type, and you want to update the original.
>>
>> I'd like to see the library automatically make the right decision for  
>> 1, and give you some mechanism to choose between 2 and 3.  To preserve  
>> existing code, 3 should be the default.
>>
>> -Steve
>
> True...
>
> Still, I find it horrible to have to create a named "dummy" variable  
> just when I simply want to pass a copy of my range.
>
> I think I found 2 other solutions:
> 1: auto ref.
> 2: Kind of like auto ref: Just provide a non-ref overload. This creates  
> less executable bloat.
>
> Like this:
> --------
> //Formatted read for R-Value input range.
> uint formattedRead(R, Char, S...)(R r, const(Char)[] fmt, S args)
> {
>      return formattedRead(r, fmt, args);
> }
> //Standard formated read
> uint formattedRead(R, Char, S...)(ref R r, const(Char)[] fmt, S args)
> --------
> This allows me to write, as I would expect:
>
> --------
> void main()
> {
>    string s = "x42xT";
>    int v;
>    formattedRead(s.save, "x%dx", &v); //Pyssing a copy
>    writefln("[%s][%s]", v, s);
>    formattedRead(s, "x%dx", &v); //Please consusme me
>    writefln("[%s][%s]", v, s);
> }
> --------
> [42][x42xT] //My range is unchanged
> [42][T]     //My range was consumed
> --------
>
> I think this is a good solution. Do you see anything I may have failed  
> to see?

Well, this does work.  But I don't like that the semantics depend on  
whether the value is an rvalue or not.

Note that even ranges that are true input ranges (i.e. a file) still  
consume their data, even as rvalues, there is no way around it.

-Steve


More information about the Digitalmars-d mailing list