Range Over Iterators in Latex

Starting with version 1.23, support for iterators has been added, which lets us range over pretty much anything!

Let’s look at the List type from the previous example again. In that example, we had an AllElements method that returned a slice of all elements in the list. With iterators, we can do it better - as shown below.

#include <iostream>
#include <functional>
#include <vector>

template <typename T>
class List;

template <typename T>
class element {
public:
    element<T>* next;
    T val;
    element(T value) : next(nullptr), val(value) {}
};

template <typename T>
class List {
public:
    element<T>* head;
    element<T>* tail;

    List() : head(nullptr), tail(nullptr) {}

    void Push(T v) {
        element<T>* newElem = new element<T>(v);
        if (tail == nullptr) {
            head = newElem;
            tail = head;
        } else {
            tail->next = newElem;
            tail = newElem;
        }
    }

    std::function<void(std::function<bool(T)>)> All() {
        return [this](std::function<bool(T)> yield) {
            for (element<T>* e = this->head; e != nullptr; e = e->next) {
                if (!yield(e->val)) return;
            }
        };
    }
};

std::function<void(std::function<bool(int)>)> genFib() {
    return [](std::function<bool(int)> yield) {
        int a = 1, b = 1;
        while (true) {
            if (!yield(a)) return;
            int next = a + b;
            a = b;
            b = next;
        }
    };
}

int main() {
    List<int> lst;
    lst.Push(10);
    lst.Push(13);
    lst.Push(23);

    lst.All()([](int e) {
        std::cout << e << std::endl;
        return true;
    });

    std::vector<int> all;
    lst.All()([&all](int e) {
        all.push_back(e);
        return true;
    });

    std::cout << "all: ";
    for (int val : all) {
        std::cout << val << " ";
    }
    std::cout << std::endl;

    genFib()([](int n) {
        if (n >= 10) return false;
        std::cout << n << std::endl;
        return true;
    });

    return 0;
}

In this translation, concepts like iterators are implemented using C++ functions and lambdas. The All method returns a lambda function that iterates over the elements in the list and calls the yield function for each element. The genFib function generates Fibonacci numbers and uses a similar lambda-based approach for iteration.

10
13
23
all: 10 13 23 
1
1
2
3
5
8

Next example: Errors.