Difference between revisions of "Higher Order Range Pattern"

From D Wiki
Jump to: navigation, search
(Solution: Process the range lazily)
m (Solution: Process the range lazily)
Line 10: Line 10:
 
<syntaxhighlight lang="d">
 
<syntaxhighlight lang="d">
 
// Simplified version of std.range.Retro
 
// Simplified version of std.range.Retro
struct Retro(range)
+
struct Retro(Range)
 
{
 
{
 
     // These functions can be inlined
 
     // These functions can be inlined

Revision as of 20:06, 7 June 2014

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]));
}