On 4/30/20 11:42 AM, Casey wrote:
On Thursday, 30 April 2020 at 13:23:25 UTC, Paul Backus wrote:
Using a default value like this means that it will be shared among all instances of the struct. Instead, you should set `buff = appender!string` in the constructor, so that each struct will have its own appender.

I'll give it a try when I get back to it (fixing lint issues), but are you sure that's the issue?  In popFront, I recreate the appender.  So, the appender should be clear before the empty check after it processes the last of the data from _input.  Still a good thing to do as a best practice; I'm just wondering if something else is causing an issue and even if initializing the appender in the constructor solves the problem, I'd be suspect of future issues cropping up.

I would say part of the issue is that you are doing all your work in front and not popFront.

What happens is that Appender is a pointer-to-implementation struct, and the compiler will allocate the first one shared amongst all initial StreamRange instances.

On your first call to front, it's going to utilize that shared one. Then on the call to popFront, it will reset it to another one.

For the second unittest, in your first call to front, it notices that it's already been filled, so it doesn't do any work (and returns the existing buffer).

another problem, your empty condition is based on the input, which violates range expectations. indeed, on the first call to front, the range all of a sudden becomes empty.

I'd say:

1. move your work to the popFront function (you then need to call popFront once before returning the range in your factory method).
2. change empty to check if the buffer is empty instead of the input.

Some other observations:

3. You don't need a further Range parameter for the nested struct, it can use the template parameter from the containing function. 4. Make it a static struct, or else it will retain a pointer to the function stack frame needlessly.

-Steve

Reply via email to