Higher Order Range Pattern
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]));
}