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

template<class RangeType>
struct range_iterator
{
	RangeType* _range;
	
	bool operator!=(const range_iterator<RangeType>& that) const {
		assert(_range == that._range);
		return !_range->empty();
	}
	
	void operator++() {
		_range->popFront();
	}
	
	typename RangeType::value_type operator*() const {
		return _range->front();
	}
};

template<class T>
struct iota
{
	typedef T value_type;
	
	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;
	}
	
	typedef range_iterator<iota<T>> iterator;
	iterator begin() { return iterator{this}; }
	iterator end() { return iterator{this}; }
	
	template<template<class InputRange> class RTy, class... Args>
	RTy<iota<T>> to(Args... args) {
		return RTy<iota<T>>(*this, args...);
	}
};

template<class R>
struct take
{
	typedef typename R::value_type value_type;
	
	R r;
	int count;
	
	take(R r, int count)
		: r(r), count(count){}
	
	value_type front() const {
		return r.front();
	}
	
	void popFront() {
		--count;
		r.popFront();
	}
	
	bool empty() const {
		return r.empty() || count == 0;
	}
	
	typedef range_iterator<take<R>> iterator;
	iterator begin() { return iterator{this}; }
	iterator end() { return iterator{this}; }
	
	template<template<class InputRange> class RTy, class... Args>
	RTy<take<R>> to(Args... args) {
		return RTy<take<R>>(*this, args...);
	}
};

template<class R>
struct filter
{
	typedef typename R::value_type value_type;
	
	R r;
	function<bool(value_type)> pred;
	
	filter(R r, const function<bool(value_type)> &pred)
		: r(r), pred(pred)
	{
		while(!r.empty() && !pred(r.front())) {
			r.popFront();
		}
	}
	
	value_type front() const {
		return r.front();
	}
	
	void popFront() {
		r.popFront();
		
		while(!r.empty() && !pred(r.front())) {
			r.popFront();
		}
	}
	
	bool empty() const {
		return r.empty();
	}
	
	typedef range_iterator<filter<R>> iterator;
	iterator begin() { return iterator{this}; }
	iterator end() { return iterator{this}; }
};

int main(int argc, const char * argv[])
{
	auto r = iota<int>(0, 10)
		.to<take>(6)
		.to<filter>([](int x){ return !(x % 2); });
	
	for(int x : r)
		printf("%d ", x);
	
	return 0;
}
