chain

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