#include <cstdio>
#include <cassert>
#include <iostream>
using namespace std;

template<class T>
struct iota
{
	T first;
	T last;
	
	iota(T first, T last)
		: first(first), last(last) {}
	
	T front() const {
		return first;
	}
	
	void popFront() {
		++first;
	}
	
	bool empty() const {
		return first == last;
	}
	
	struct iterator
	{
		iota *_iota;
		
		bool operator!=(const iterator& that) const {
			assert(_iota == that._iota);
			return !_iota->empty();
		}
		
		void operator++() {
			_iota->popFront();
		}
		
		T operator*() const {
			return _iota->front();
		}
	};
	
	iterator begin() { return iterator{this}; }
	iterator end() { return iterator{this}; }
	
	template<template<class _T, class S> class R, class... Args>
	R<T, iota<T>> to(Args... args) {
		return R<T, iota<T>>(args..., this);
	}
};

template<class T, class R>
struct take
{
	R* r;
	int count;
	
	take(int count, R* r) : r(r), count(count){}
	
	T front() const {
		return r->front();
	}
	
	void popFront() {
		--count;
		r->popFront();
	}
	
	bool empty() const {
		return r->empty() || count == 0;
	}
	
	struct iterator
	{
		take *_take;
		
		bool operator!=(const iterator& that) const {
			assert(_take == that._take);
			return !_take->empty();
		}
		
		void operator++() {
			_take->popFront();
		}
		
		T operator*() const {
			return _take->front();
		}
	};
	
	iterator begin() { return iterator{this}; }
	iterator end() { return iterator{this}; }
};

int main(int argc, const char * argv[])
{
	for(int x : iota<int>(0, 5).to<take>(3))
		printf("%d ", x);
	
    return 0;
}