Adapting foreign iterators to D ranges

Salih Dincer salihdb at hotmail.com
Mon Sep 30 12:04:09 UTC 2024


On Thursday, 25 April 2024 at 03:18:36 UTC, cc wrote:
> On Wednesday, 24 April 2024 at 05:08:25 UTC, Salih Dincer wrote:
>> Yes, `opApply()` works! You just need to use `do while()` 
>> instead of `while()` because it skips the first item.
>
> It depends on the type of structure being consumed, if it 
> provides "next" as a direct pointer then yeah you would need to 
> consume the item first before iterating to the next in line.  
> However some APIs provide an opaque iterator type where you 
> call a "next" method to get the first element, IIRC Lua does 
> something like this.

I've noticed a strange behavior in the Range structure that 
consumes the List class! If we use foreach(), we should take a 
backup as we're used to, or use the rewind() function as I did 
below. These days, I've started to delve deeper into the 
opApply() feature. I wanted to fix this mistake I made in the 
past.

```d
struct Range
{
   private List list;

   int opApply(scope int delegate(Node* t) dg)
   {
     while(auto current = list.Next)
     {
       if (auto r = dg(current))
         return r;
     }
     list.rewind();
     return 0;
   }
}
```

Also, due to the nature of linked lists, we cannot print the 
number 1 added at the beginning with foreach(). Therefore, when 
creating the List class, it may be wise to create it without 
giving any parameters and start adding elements from 1. You might 
also be interested in this topic about opApply:

https://forum.dlang.org/thread/jxzqsxasierzokgcykjh@forum.dlang.org

SDB at 79


More information about the Digitalmars-d-learn mailing list