buffered input

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sat Feb 5 07:32:36 PST 2011


On 2/5/11 8:41 AM, Tomek Sowiński wrote:
> Andrei Alexandrescu napisał:
>
>> I hereby suggest we define "buffered input range of T" any range R
>> that satisfies the following conditions:
>>
>> 1. R is an input range of T[]
>>
>> 2. R defines a primitive shiftFront(size_t n). The semantics of
>> the primitive is that, if r.front.length>= n, then shiftFront(n)
>> discards the first n elements in r.front. Subsequently r.front will
>> return a slice of the remaining elements.
>>
>> 3. R defines a primitive appendToFront(size_t n). Semantics: adds
>> at most n more elements from the underlying stream and makes them
>> available in addition to whatever was in front. For example if
>> r.front.length was 1024, after the call r.appendToFront(512) will
>> have r.front have length 1536 of which the first 1024 will be the
>> old front and the rest will be newly-read elements (assuming that
>> the stream had enough data). If n = 0, this instructs the stream to
>> add any number of elements at its own discretion.
>
> I don't see a clear need for the two to be separate. Could they fold
> into popFront(n, m) meaning shiftFront(n); appendToFront(m) ? Nullary
> popFront() discards all and loads any number it pleases.

I think combining the two into one hurts usability as often you want to 
do one without the other.

>> This is it. I like many things about this design, although I still
>> fear some fatal flaw may be found with it.
>>
>> With these primitives a lot of good operating operating on
>> buffered streams can be written efficiently. The range is allowed
>> to reuse data in its buffers (unless that would contradict language
>> invariants, e.g. if T is invariant), so if client code wants to
>> stash away parts of the input, it needs to make a copy.
>
> Some users would benefit if they could just pass in a buffer and say
> "fill'er up".

Correct. That observation applies to unbuffered input as well.

>> One great thing is that buffered ranges as defined above play very
>> well with both ranges and built-in arrays - two quintessential
>> parts of D. I look at this and say, "this all makes sense". For
>> example the design could be generalized to operate on some
>> random-access range other than the built-in array, but then I'm
>> thinking, unless some advantage comes about, why not giving T[] a
>> little special status? Probably everyone thinks of contiguous
>> memory when thinking "buffers", so here generalization may be
>> excessive (albeit meaningful).
>
> Contiguous, yes. But I'd rather see front() exposing, say, a circular
> buffer so that appendToFront(n) reallocates only when n>
> buf.length.
>

I think circularity is an implementation detail that is poor as a 
client-side abstraction.


Andrei


More information about the Digitalmars-d mailing list