Higher Order Range Pattern

From D Wiki
Revision as of 07:12, 1 March 2014 by Verax (talk | contribs) (Solution: Process the range lazily)
Jump to: navigation, search

From David Simcha's D-Specific Design Patterns talk at DConf 2013.

Problem: Need to transform a range before passing to a function/object

Want:

  • O(1) auxiliary memory usage
  • O(1) preprocessing time
  • Minimal wasted effort if only part of the range is consumed.

Solution: Process the range lazily

// Simplified version of std.range.Retro
struct Retro(range)
{
    // These functions can be inlined
    @property
    {
        auto ref front() { return range_.back;  }
        auto ref back()  { return range_.front; }
        bool empty()     { return range_.empty; }
    }

    void popFront() { range_.popBack();  }
    void popBack()  { range_.popFront(); }

    Range range_;
}

// Instantiator function
auto retro(Range)(Range range)
{
    return Retro!Range(range);
}

void main()
{
    import std.algorithm;

    auto arr = [1, 2, 3, 4, 5];
    assert(equal(retro(arr), [5, 4, 3, 2, 1]));
}