*Should* char[] be an output range?

monarch_dodra monarchdodra at gmail.com
Wed Sep 4 00:48:47 PDT 2013


On Wednesday, 4 September 2013 at 05:00:58 UTC, Jonathan M Davis 
wrote:
> The main problem has to do with what you do when there's not 
> enough room to
> write to it. Even checking the length isn't enough, because 
> it's unknown ahead
> of time whether a particular code point (or string of 
> characters if calling
> put with multiple characters) will fit - at least not without 
> converting the
> character to UTF-8 first, which would incur additional cost, 
> since presumably
> that would result in it being converted twice (once to check 
> and once when
> actually putting it).
>
> Of course, it's a problem in general with output ranges that we 
> haven't defined
> how to check whether put will succeed or what the normal 
> procedure is when
> it's going to fail. My first suggestion for that would be to 
> make it so that
> put returned whether it was successful or not, but it's 
> something that
> probably needs to be discussed. However, with that problem 
> solved, it may be
> reasonable to make char[] an output range.
>
> But until we sort out some of the remaining details of output 
> ranges (most
> particularly how to deal with put failing, but there are 
> probably other issues
> that I'm not thinking of at the moment), I don't think that 
> it's a good idea
> to change how char[] is treated, since how all of that is 
> sorted out could
> have an effect on what we do with char[].
>
> - Jonathan M Davis

Thanks for your reply. Yeah, the debate always boils back down to 
what "are arrays/input ranges output ranges, and what do we do 
when they are "full" (eg empty), and can we even detect it".

I think that given your answer, I will simply *not* make them 
output ranges, but I *will* make sure that making them as such is 
easy.

FYI (but it might need a little bit more work), I think I may be 
on to something. In my implementation, I defined a private 
function called "doPut". "doPut" is basically the last "atomic" 
operation in the "put" functionality.

Given a sink "s", and an element "e", it calls exactly the 
correct call of :
s.put(e);
s.front = e;
s(e);

It does *not* iterate over "e", if it is a range. It does *not* 
attempt to check [e], and it does *not* transcode "e". What this 
means is that basically, if you write "doPut(s, e)", then you are 
putting *exactly* the single element "e" into "s". It means the s 
is a "native" output range for "e": It doesn't need any help from 
"put".

 From there, I defined the package trait "isNativeOutputRange(S, 
E)". If a pair S/E verify this "Native" variant of isOutputRange, 
then the user has the *guarantee* that "put(s, e)" will place 
*exactly* "e" into "s". This is particularly interesting for:
1. InputRanges: if the range is not empty, the *put* is guarateed 
to not overflow.
2. Certain format functions, such as "std.encoding.encode(C, 
S)(dchar c, S sink)", will transcode c into elements of type C, 
and place them in the output range S. Here, it is *vital* that no 
transcoding happen. My "doPut"/Native trait help guarantee this.

--------

Well, right now, it is only used as private implementation 
detail, but it works pretty good. It might be worth investigating 
in more details if we want this public?


More information about the Digitalmars-d mailing list