You can always code this by hand. Truthfully, yield
really seems like sugar coating to me (and co-routines too).
What a coroutine is, really ? Some state bundled up together with:
- one function to create it (isn't it a constructor ?)
- one function to move to the next state (isn't it operator++, traditionally ?)
In C++, it's called an InputIterator
, and can be arbitrarily fat.
So, it's true that the syntax won't be as pretty, but this should do, just with the Standard Library:
static std::array<int, 6> const Array = {{1, 2, 4, 8, 16, 16777216}};
class Integers: public std::iterator<std::input_iterator_tag,
int, ptrdiff_t, int const*, int>
{
public:
Integers(): _index(0) {}
operator bool() const { return _index < Array.size(); }
Integers& operator++() { assert(*this); ++_index; return *this; }
Integers operator++(int) { Integers tmp = *this; ++*this; return tmp; }
int operator*() const { assert(*this); return Array[_index]; }
int const* operator->() const { assert(*this); return &Array[_index]; }
private:
size_t _index;
}; // class Integers
And obviously, since you decide exactly what state is stored, you decide if all is pre-computed or if part (or whole of it) is lazily computed, and possibly cached, and possibly multi-threaded, and ... you got the idea :)
yield
does behind the scenes in blogs.msdn.com/b/oldnewthing/archive/2008/08/12/8849519.aspx. – Nanna