Thread overview | ||||||
---|---|---|---|---|---|---|
|
July 29, 2012 Ranges and backward iteration | ||||
---|---|---|---|---|
| ||||
I have a use case where I would like to be able to pass both a forward and backward iteration of an array to a function: void foo(InputR, OutputR)(InputR i, OutputR j) if (isInputRange!InputR && isOutputRange!(OutputR, InputR)) { ... } main() { //forward: foo(a[1..n], b[1..n]); //backward: foo(retro(a[n..$]), retro(b[n..$])); //do stuff with b as it has been constructed now... } This doesn't work (retro doesn't appear to return a Range, but rather an object of type "Result", which I don't understand), but the intent should be clear. How do I do this? What am I missing? There doesn't seem to be a "backward iterator" equivalent in std.range. |
July 29, 2012 Re: Ranges and backward iteration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew | On Sunday, 29 July 2012 at 23:26:09 UTC, Andrew wrote:
> I have a use case where I would like to be able to pass both a
> forward and backward iteration of an array to a function:
>
> void foo(InputR, OutputR)(InputR i, OutputR j)
> if (isInputRange!InputR && isOutputRange!(OutputR, InputR))
> {
> ...
> }
>
> main()
> {
> //forward:
> foo(a[1..n], b[1..n]);
> //backward:
> foo(retro(a[n..$]), retro(b[n..$]));
>
> //do stuff with b as it has been constructed now...
> }
>
> This doesn't work (retro doesn't appear to return a Range, but
> rather an object of type "Result", which I don't understand), but
> the intent should be clear.
>
> How do I do this? What am I missing? There doesn't seem to be a
> "backward iterator" equivalent in std.range.
isBidirectionalRange perhaps?
[quote]
Returns true if R is a bidirectional range. A bidirectional range is a forward range that also offers the primitives back and popBack. The following code should compile for any bidirectional range.
[/quote]
|
July 29, 2012 Re: Ranges and backward iteration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew | On 07/30/2012 01:26 AM, Andrew wrote: > I have a use case where I would like to be able to pass both a > forward and backward iteration of an array to a function: > > void foo(InputR, OutputR)(InputR i, OutputR j) > if (isInputRange!InputR && isOutputRange!(OutputR, InputR)) > { > ... > } > > main() > { > //forward: > foo(a[1..n], b[1..n]); > //backward: > foo(retro(a[n..$]), retro(b[n..$])); > > //do stuff with b as it has been constructed now... > } > > This doesn't work Works for me. This is how I test: void foo(InputR, OutputR)(InputR i, OutputR j) if (isInputRange!InputR && isOutputRange!(OutputR, InputR)){ j.put(i); } void main() { int[] a=[2,0,0,3], b=[1,2,3,4]; int n=2; foo(a[0..n], b[0..n]); assert(b==[2,0,3,4]); foo(retro(a[n..$]), retro(b[n..$])); assert(b==[2,0,0,3]); } > (retro doesn't appear to return a Range, but > rather an object of type "Result", which I don't understand) 'Result' implements the range interface and is a local struct of the 'retro' function. >, but the intent should be clear. > > How do I do this? What am I missing? There doesn't seem to be a > "backward iterator" equivalent in std.range. retro should do the job. |
July 29, 2012 Re: Ranges and backward iteration | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Sunday, 29 July 2012 at 23:42:09 UTC, Timon Gehr wrote:
> On 07/30/2012 01:26 AM, Andrew wrote:
>> I have a use case where I would like to be able to pass both a
>> forward and backward iteration of an array to a function:
>>
>> void foo(InputR, OutputR)(InputR i, OutputR j)
>> if (isInputRange!InputR && isOutputRange!(OutputR, InputR))
>> {
>> ...
>> }
>>
>> main()
>> {
>> //forward:
>> foo(a[1..n], b[1..n]);
>> //backward:
>> foo(retro(a[n..$]), retro(b[n..$]));
>>
>> //do stuff with b as it has been constructed now...
>> }
>>
>> This doesn't work
>
> Works for me.
>
> This is how I test:
>
> void foo(InputR, OutputR)(InputR i, OutputR j) if (isInputRange!InputR && isOutputRange!(OutputR, InputR)){
> j.put(i);
> }
>
> void main() {
> int[] a=[2,0,0,3], b=[1,2,3,4];
> int n=2;
> foo(a[0..n], b[0..n]);
> assert(b==[2,0,3,4]);
> foo(retro(a[n..$]), retro(b[n..$]));
> assert(b==[2,0,0,3]);
> }
>
>> (retro doesn't appear to return a Range, but
>> rather an object of type "Result", which I don't understand)
>
> 'Result' implements the range interface and is a local struct of the 'retro' function.
>
>>, but the intent should be clear.
>>
>> How do I do this? What am I missing? There doesn't seem to be a
>> "backward iterator" equivalent in std.range.
>
> retro should do the job.
Awesome, thanks... In my code, I had a "ref" for the second
argument, which apparently made the type signature not work.
|
Copyright © 1999-2021 by the D Language Foundation