Possible range idiom that I find useful, especially in @nogc

Tofu Ninja via Digitalmars-d digitalmars-d at puremagic.com
Thu Aug 25 17:17:28 PDT 2016


So this is a small thing but I find it definitely useful in my 
own ranges and wished the ranges in phobos did this.

A lot of ranges in phobos take an alias to a function and somehow 
use that to generate the output range, for example map. But it 
can be annoying when your map function needs extra data to 
perform the map. Example...

auto foo(R)(R range, int x) {
      return range.map!((v)=>(v+x));
}

That works perfectly well because it will allocate a closure and 
make it work. But if foo was @nogc then it would fail. If you are 
trying to avoid the gc, the basic range functions get pretty 
annoying to use.

One thing I have started doing with any of my range generators 
that take an alias to a function is to have an extra ARGS... 
argument tacked in on the end. Then the range that gets generated 
will save the extra args into the resulting range struct and pass 
them back into the alias function whenever it needs to be called.

Example:

auto RangeGenerator(alias pred, ARGS...)(ARGS args) {
     // Range struct
     struct Range {
         private ARGS extra;
         // range implementation that somehow calls pred
         // If pred is normally takes a single argument, similar 
to map, like pred(item)
         // then I would instead call pred(item, extra)
     }
     Range r;
     r.extra = args;
     /// any other setup
     return r;
}


I use this alot, for example I have an octree implementation that 
provides range interface to iterate the items that lie in a 
specific region in space. The region is defined by a region 
function that takes an axis aligned bounding box and returns true 
or false if it lies in the region. But a lot of times the region 
function needs extra arguments to do the test, but I can't rely 
on gc allocated closures to make it possible. So instead I just 
pass the extra data into the range generator and have it saved 
into the resulting range struct. It works extremely well and 
means I don't need to use the GC.

I don't know if anyone else ever has this problem but I just 
thought I would share.





More information about the Digitalmars-d mailing list