digitalmars.D - Make std.container.Array an output range
- Rene Zwanenburg (13/13) Jun 05 2014 I depend heavily on RAII in a project I'm working on. Since
- monarch_dodra (10/24) Jun 05 2014 Well, one issue is that for a "Range", "put" really just means
- monarch_dodra (24/35) Jun 05 2014 Just to clarify, I think that means that MAKING Array an output
- Rene Zwanenburg (6/34) Jun 05 2014 Agreed. This is much nicer.
- Dmitry Olshansky (5/16) Jun 06 2014 I think we all understand that not every container has one and holy
I depend heavily on RAII in a project I'm working on. Since structs in dynamic arrays never have their destructors called I'm using Array!T instead. A pattern that comes up often is that I have some input range of T's which need to be stored in a member Array!T. However Array is not an output range so I can't use inputRange.copy(someArray); I understand the difference between a container and a range iterating over that container. However I do think a container is an output range. Should I file an enhancement request or is there something fundamentally wrong with this idea? For Array it should be as simple as adding alias doPut = insertBack;
Jun 05 2014
On Thursday, 5 June 2014 at 13:51:35 UTC, Rene Zwanenburg wrote:I depend heavily on RAII in a project I'm working on. Since structs in dynamic arrays never have their destructors called I'm using Array!T instead. A pattern that comes up often is that I have some input range of T's which need to be stored in a member Array!T. However Array is not an output range so I can't use inputRange.copy(someArray); I understand the difference between a container and a range iterating over that container. However I do think a container is an output range. Should I file an enhancement request or is there something fundamentally wrong with this idea? For Array it should be as simple as adding alias doPut = insertBack;Well, one issue is that for a "Range", "put" really just means overwrite the front element, and pop it. So... Array!int myArray = ...: copy([1, 2, 3], myArray); //(1) copy([1, 2, 3], myArray[]); //(2) In this situation, (1) and (2) would have different meaning. This whole mess comes from "Writeable InputRange" being considered an OutputRange... Arguably, an OutputRange should be nothing more than a "sink", which an InputRange is not.
Jun 05 2014
On Thursday, 5 June 2014 at 16:21:21 UTC, monarch_dodra wrote:Well, one issue is that for a "Range", "put" really just means overwrite the front element, and pop it. So... Array!int myArray = ...: copy([1, 2, 3], myArray); //(1) copy([1, 2, 3], myArray[]); //(2) In this situation, (1) and (2) would have different meaning.Just to clarify, I think that means that MAKING Array an output range is a bad idea, for the same reasons that vector is not an output iterator. That said, having an explicit OutputRange adapator: struct BackInserter(Container) { Container* c; void put(T)(ref T t) { c.insertBack(t); } } auto backInserter(Container)(ref Container c) { return BackInserter!Container(&c); } Useage: inputRange.copy(someArray.backInserter()); There: Clear and un-ambiguous.doPut is not a range primitive. Implementing "doPut" on your container should have no effect. If it does, it is a bug and will *quickly* be fixed. Don't count on it working. The correct primitive is "put".Should I file an enhancement request or is there something fundamentally wrong with this idea? For Array it should be as simple as adding alias doPut = insertBack;
Jun 05 2014
On Thursday, 5 June 2014 at 16:29:09 UTC, monarch_dodra wrote:On Thursday, 5 June 2014 at 16:21:21 UTC, monarch_dodra wrote:I see. I wasn't aware of that.Well, one issue is that for a "Range", "put" really just means overwrite the front element, and pop it. So...That said, having an explicit OutputRange adapator: struct BackInserter(Container) { Container* c; void put(T)(ref T t) { c.insertBack(t); } } auto backInserter(Container)(ref Container c) { return BackInserter!Container(&c); } Useage: inputRange.copy(someArray.backInserter()); There: Clear and un-ambiguous.Agreed. This is much nicer.Thanks. I skimmed the documentation for std.range.put a bit too fast :). Reading it more carefully I see it also mentions your first point regarding front + popFront.doPut is not a range primitive. Implementing "doPut" on your container should have no effect. If it does, it is a bug and will *quickly* be fixed. Don't count on it working. The correct primitive is "put".Should I file an enhancement request or is there something fundamentally wrong with this idea? For Array it should be as simple as adding alias doPut = insertBack;
Jun 05 2014
05-Jun-2014 17:51, Rene Zwanenburg пишет:I depend heavily on RAII in a project I'm working on. Since structs in dynamic arrays never have their destructors called I'm using Array!T instead. A pattern that comes up often is that I have some input range of T's which need to be stored in a member Array!T. However Array is not an output range so I can't use inputRange.copy(someArray); I understand the difference between a container and a range iterating over that container. However I do think a container is an output range. Should I file an enhancement request or is there something fundamentally wrong with this idea? For Array it should be as simple as adding alias doPut = insertBack;I think we all understand that not every container has one and holy insertion policy. How about adding Array.backInserter ? -- Dmitry Olshansky
Jun 06 2014