digitalmars.D.learn - Ranges and backward iteration
- Andrew (20/20) Jul 29 2012 I have a use case where I would like to be able to pass both a
- Era Scarecrow (8/29) Jul 29 2012 isBidirectionalRange perhaps?
- Timon Gehr (18/39) Jul 29 2012 Works for me.
- Andrew (3/47) Jul 29 2012 Awesome, thanks... In my code, I had a "ref" for the second
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.
Jul 29 2012
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]
Jul 29 2012
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 workWorks 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.
Jul 29 2012
On Sunday, 29 July 2012 at 23:42:09 UTC, Timon Gehr wrote:On 07/30/2012 01:26 AM, Andrew wrote:Awesome, thanks... In my code, I had a "ref" for the second argument, which apparently made the type signature not work.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 workWorks 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.
Jul 29 2012