generator

Source code

ranges-compatible generator type built on C++20 coroutines.

template<class T>
class tl::generator

A generator allows implementing sequence producers which are terse and avoid creating the whole sequence in memory.

Example:

tl::generator<int> iota(int i = 0) {
    while(true) {
        co_yield i;
        ++i;
    }
}

Member Types

class promise_type
class sentinel
class iterator

Member Types

using value_type = std::remove_reference_t<T>
using reference_type = value_type&
using pointer_type = value_type *
using difference_type = std::ptrdiff_t

Special Members

iterator() = delete

The iterators should only be created by tl::generator<T>::begin

iterator(iterator const&)
iterator &operator=(iterator const&)

Coroutine handles point to a unique resource, so the iterators are not copyable.

iterator(generator &&rhs) noexcept
iterator &operator=(generator &&rhs) noexcept

Takes the coroutine handle from rhs, making rhs not tied to a coroutine.

Member Functions

friend bool operator==(iterator const &it, sentinel) noexcept

Returns true if the iterator has been moved from, or if the coroutine it is tied to has completed.

iterator &operator++()
void operator++(int)

Resumes the coroutine until return/co_yield/exception and returns an iterator which can be used to retrieve the yielded value and drive the coroutine forward again.

Rethrows the exception if one occurred.

reference_type operator*()

Returns the last value yielded.

using promise_type = promise
using handle_type = std::coroutine_handle<promise_type>

Special Members

generator()

Creates a generator which is not tied to a coroutine.

generator(generator const&) = delete
generator &operator=(generator const&) = delete

Coroutine handles point to a unique resource, so generators are not copyable.

generator(generator &&rhs) noexcept
generator &operator=(generator &&rhs) noexcept

Takes the coroutine handle from rhs, making rhs not tied to a coroutine.

Member Functions

iterator begin()

Resumes the coroutine until return/co_yield/exception and returns an iterator which can be used to retrieve the yielded value and drive the coroutine forward again.

Rethrows the exception if one occurred.

Calling begin twice on the same generator is undefined behaviour.

sentinel end() const noexcept
void swap(generator &other) noexcept
template <class T> inline constexpr bool std::ranges::enable_view<tl::generator<T>> = true

tl::generator<T> is a view.