Difference between revisions of "Higher Order Range Pattern"

From D Wiki
Jump to: navigation, search
(Solution: Process the range lazily)
(Solution: Process the range lazily)
Line 24: Line 24:
  
 
     Range range_;
 
     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]));
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>

Revision as of 07:12, 1 March 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]));
}