deprecating std.stream, std.cstream, std.socketstream

Steven Schveighoffer schveiguy at yahoo.com
Wed May 16 13:15:22 PDT 2012


On Wed, 16 May 2012 15:38:02 -0400, H. S. Teoh <hsteoh at quickfur.ath.cx>  
wrote:

> On Wed, May 16, 2012 at 12:48:49PM -0500, Andrei Alexandrescu wrote:
>> On 5/16/12 12:34 PM, Steven Schveighoffer wrote:
>> >In other words, ranges aren't enough.
>>
>> This is copiously clear to me, but the way I like to think about it
>> is by extending the notion of range (with notions such as e.g.
>> BufferedRange, LookaheadRange, and such) instead of developing an
>> abstraction independent from ranges and then working on stitching
>> that with ranges.
> [...]
>
> One direction that _could_ be helpful, perhaps, is to extend the concept
> of range to include, let's tentatively call it, a ChunkedRange.
> Basically a ChunkedRange implements the usual InputRange operations
> (empty, front, popfront) but adds the following new primitives:
>
> - bool hasAtLeast(R)(R range, int n) - true if underlying range has at
>   least n elements left;
>
> - E[] frontN(R)(R range, int n) - returns a slice containing the front n
>   elements from the range: this will buffer the next n elements from the
>   range if they aren't already; repeated calls will just return the
>   buffer;
>
> - void popN(R)(R range, int n) - discards the first n elements from the
>   buffer, thus causing the next call to frontN() to fetch more data if
>   necessary.
>

On such ranges, what would popFront and front do?  I'm assuming since  
frontN and popN are referring to how many elements, and since the most  
logical definition for elements is bytes, that front gets the next byte,  
and popFront discards the next byte.  This seems useless to me.

I still don't get the need to "add" this to ranges.  The streaming API  
works fine on its own.

But there is an omission with your proposed API regardless -- reading data  
is a mutating event.  It destructively mutates the underlying data stream  
so that you cannot get the data again.  This means you must double-buffer  
data in order to support frontN and popN that are not necessary with a  
simple read API.

For example:

auto buf = new ubyte[1000000];
stream.read(buf);

does not need to first buffer the data inside the stream and then copy it  
to buf, it can read it from the OS *directly* into buf.

-Steve


More information about the Digitalmars-d mailing list