#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;

template <class F>
class generator{
public:
//typedefs required for iterator-use
typedef typename F::value_type value_type;
typedef typename F::step_type step_type;
typedef value_type * pointer;
typedef value_type & reference;
typedef typename F::size_type size_type;
typedef typename F::difference_type difference_type;
typedef std::bidirectional_iterator_tag iterator_category;

generator(value_type init, step_type step) : t(init), step(step){}

generator<F> &operator++() {
    t += step; return *this;
}

generator<F> &
operator+=(size_type n)
{
    t += n * step;
    return *this;
}

generator<F>
operator+(size_type n)
{
    return generator(*this) += n;
}

value_type operator*() const {
    return f(t);
}

friend bool operator==(const generator<F> &lhs, const generator<F> &rhs){
        return lhs.t == rhs.t;
}
friend bool operator!=(const generator<F> &lhs, const generator<F> &rhs){
        return !(lhs == rhs);
}
private:
    value_type t;
    value_type step;
    F f;
};

template <typename T>
    struct simple_generator_function
    {
        typedef T value_type;
        typedef T step_type;
        typedef T difference_type;
        typedef size_t size_type;
    };
    
    template <typename T>
    struct square_generator : public simple_generator_function<T> {
    
        T operator()(T t) const{
            return t * t;
        }
    };


int main(void) {
        using int_sqg = generator<square_generator<int>>;
        int_sqg gen(1, 1);
        vector<int> v(gen, gen+10);
        copy(begin(v), end(v), ostream_iterator<int>(cout, ","));
        cout << '\n';
    }