cIterableをつなげます。
template<typename T> class cChain : public cIterable<T> { shared_ptr<cIterable<T>> gen1; shared_ptr<cIterable<T>> gen2; bool first; public: cChain(shared_ptr<cIterable<T>> g1, shared_ptr<cIterable<T>> g2) : gen1(g1), gen2(g2), first(true) { } bool exists_next() { if(first) { if(!gen1->exists_next()) { first = false; return gen2->exists_next(); } else { return true; } } else { return gen2->exists_next(); } } T value() const { return first ? gen1->value() : gen2->value(); } }; template<typename T> shared_ptr<cIterable<T>> chain(shared_ptr<cIterable<T>> g1, shared_ptr<cIterable<T>> g2) { return shared_ptr<cIterable<T>>(new cChain<T>(g1, g2)); } int main() { cout << chain(range(2), range(3)) << endl; // 0 1 0 1 2 }
これでは2つしかつなげられません。3つ以上でもつなげたいですね。しかし、VC10では可変長引数を実現するにはいまだにva_listとか使わなければならない? しかたがないので、4つまでを定義しておきました。
template<typename T> shared_ptr<cIterable<T>> chain(shared_ptr<cIterable<T>> g1, shared_ptr<cIterable<T>> g2, shared_ptr<cIterable<T>> g3) { return shared_ptr<cIterable<T>>(new cChain<T>(g1, chain(g2, g3))); } template<typename T> shared_ptr<cIterable<T>> chain( shared_ptr<cIterable<T>> g1, shared_ptr<cIterable<T>> g2, shared_ptr<cIterable<T>> g3, shared_ptr<cIterable<T>> g4) { return shared_ptr<cIterable<T>>( new cChain<T>(g1, chain(g2, chain(g3, g4)))); } int main() { cout << chain(range(2), range(3), range(2)) << endl; }
0 1 0 1 2 0 1