#ifndef MORON_H #define MORON_H template class xx_zip_iter{ T1 t1; T2 t2; public: xx_zip_iter(T1 &&a1, T2 &&a2){ t1 = a1; t2 = a2; } xx_zip_iter & operator ++(){ ++t1; ++t2; return *this; } bool operator != (const xx_zip_iter &x) const{ // Both must be different. Not intuitive here. We want to loop // continue while both are != end return t1 != x.t1 && t2 != x.t2; } auto operator *() const{ return std::pair(*t1,*t2); } }; template class zip_iter{ public: T1 &t1; T2 &t2; zip_iter(T1 &a1, T2 &a2): t1(a1), t2(a2){ //if (t1.size() != t2.size()) fprintf (stderr,"zip_iter: Wrong size %lu != %lu\n",t1.size(),t2.size()); //if (size(t1) != size(t2)) fprintf (stderr,"zip_iter: Wrong size %lu != %lu\n",size(t1),size(t2)); } }; template auto begin(zip_iter &z) -> xx_zip_iter{ return xx_zip_iter(begin(z.t1),begin(z.t2)); } template auto end(zip_iter &z) -> xx_zip_iter{ return xx_zip_iter(end(z.t1),end(z.t2)); } template zip_iter zip(T1 &t1, T2 &t2){ return zip_iter(t1,t2); } template< class T> std::pair maxval(const std::vector &v) { std::pair ret; ret.first = 0; ret.second = v[0]; for (unsigned i=1; i ret.second){ ret.first = i; ret.second = vi; } } return ret; } typename boost::coroutines2::coroutine::pull_type readlines(FILE *fin) { return typename boost::coroutines2::coroutine::pull_type( [&](boost::coroutines2::coroutine::push_type& sink){ FILE *f = fin; char line[1000]; while (fgets(line,sizeof(line),f)!=NULL){ printf ("sink %s",line); sink(line); } }); } template < class T1> typename boost::coroutines2::coroutine::pull_type shuffle(std::vector &v1, int n) { return typename boost::coroutines2::coroutine::pull_type ( [&](typename boost::coroutines2::coroutine::push_type& sink){ int nn = n; for (int i=0; i::pull_type random_iter(int n) { return typename boost::coroutines2::coroutine::pull_type( [&](boost::coroutines2::coroutine::push_type& sink){ printf ("random n=%d\n",n); int ln = n; for (int i=0; i