www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is it possible to use a template to choose between foreach and

reply pineapple <meapineapple gmail.com> writes:
It would be fantastic if I could write this -

     static if(forward){
         foreach(item; items) dostuff();
     }else{
         foreach_reverse(item; items) dostuff();
     }

as something like this -

     foreach!forward(item; items) dostuff();

Is there any way to accomplish this?
Jun 04 2016
next sibling parent reply Mihail K <mihail platterz.ca> writes:
On Saturday, 4 June 2016 at 14:32:23 UTC, pineapple wrote:
 It would be fantastic if I could write this -

     static if(forward){
         foreach(item; items) dostuff();
     }else{
         foreach_reverse(item; items) dostuff();
     }

 as something like this -

     foreach!forward(item; items) dostuff();

 Is there any way to accomplish this?
As far as I recall, foreach_reverse is deprecated in favour of range operations. ie. import std.algorithm, std.range; static if(forward) { items.each!(item => doStuff()); } else { items.retro.each!(item => doStuff()); } As for your question, I suggest writing a range function that calls retro conditionally. Something like, items.direction!(forward).each!(item => doStuff());
Jun 04 2016
parent reply pineapple <meapineapple gmail.com> writes:
On Saturday, 4 June 2016 at 15:43:01 UTC, Mihail K wrote:
 As far as I recall, foreach_reverse is deprecated in favour of 
 range operations.
 ie.

   import std.algorithm, std.range;

   static if(forward)
   {
       items.each!(item => doStuff());
   }
   else
   {
       items.retro.each!(item => doStuff());
   }

 As for your question, I suggest writing a range function that 
 calls retro conditionally. Something like,

   items.direction!(forward).each!(item => doStuff());
Won't this pattern fail if items is a type implementing opApply and/or opApplyReverse?
Jun 04 2016
parent reply AbstractGuy <ab-g nowhere.ae> writes:
On Saturday, 4 June 2016 at 17:16:45 UTC, pineapple wrote:
 Won't this pattern fail if items is a type implementing opApply 
 and/or opApplyReverse?
opApply/ApplyReverse predates the detection of the input/bidir range primitives. It's specified in the language. If an aggregate implements both than the operator overloads are privilegiated.
Jun 04 2016
parent Mike Parker <aldacron gmail.com> writes:
On Saturday, 4 June 2016 at 21:52:31 UTC, AbstractGuy wrote:
 On Saturday, 4 June 2016 at 17:16:45 UTC, pineapple wrote:
 Won't this pattern fail if items is a type implementing 
 opApply and/or opApplyReverse?
opApply/ApplyReverse predates the detection of the input/bidir range primitives. It's specified in the language. If an aggregate implements both than the operator overloads are privilegiated.
Only when using foreach and foreach_reverse do opApply/Reverse get priority. The same does not hold with retro, which only operates on ranges.
Jun 04 2016
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 06/04/2016 07:32 AM, pineapple wrote:
 It would be fantastic if I could write this -

     static if(forward){
         foreach(item; items) dostuff();
     }else{
         foreach_reverse(item; items) dostuff();
     }

 as something like this -

     foreach!forward(item; items) dostuff();

 Is there any way to accomplish this?
I agree with Mihail K. that retro() should be preferred. However, some iteration like tree iteration can be simpler with the function call stack, which opApply and opApplyReverse automatically take advantage of. enum Direction { forward, backward } void foo(Direction dir = Direction.backward)() { static if (dir == Direction.forward) { } else { } } void main() { foo!(Direction.forward)(); foo!(Direction.backward)(); foo(); } Ali
Jun 04 2016