If a foreach is encountered by the compiler

foreach(element; range) {

it's internally rewritten similar to the following:

for (; !range.empty; range.popFront()) {
    auto element = range.front;

Any object which fulfills the above interface is called a range and is thus a type that can be iterated over:

struct Range {
    @property empty() const;
    void popFront();
    T front();

The functions in std.range and std.algorithm provide building blocks that make use of this interface. Ranges allow to compose complex algorithms behind an object that can be iterated with ease. Furthermore ranges allow to create lazy objects that only perform a calculation when it's really needed in an iteration e.g. when the next range's element is accessed. Special range algorithm will be presented later in the D's Gems section.


Complete the source code to create the FibonacciRange range that returns numbers of the Fibonacci sequence. Don't fool yourself into deleting the assertions!


rdmd playground.d