Difference between revisions of "Higher Order Range Pattern"
(→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]));
}