Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

copy-like algorithm with four iterators

Is there a std::copy-like algorithm that accepts four iterators, denoting two ranges?

Basically, it should stop copying as soon as either range is exhausted:

template<typename Iter>
void copy_range(Iter begin1, Iter end1, Iter begin2, Iter end2)
{
    for (; (begin1 != end1) && (begin2 != end2); ++begin1, ++begin2)
    {
         *begin2 = *begin1;
    }
}
like image 393
fredoverflow Avatar asked Jul 19 '12 12:07

fredoverflow


1 Answers

No there is no such thing sadly. The closest thing is std::copy_n.

And of course the algorithm you just wrote.

Depending on the type of iterator used (random or not), using this is more efficient (because only one check needs to be made for each iteration) than your algorithm:

std::copy_n(begin1,
            std::min(std::distance(begin1, end1), std::distance(begin2, end2)),
            begin2);

Another alternative is a checked output iterator, something along the lines of this (rough sketch, not checked code):

template<class Iter>
class CheckedOutputIter {
public:
    // exception used for breaking loops
    class Sentinel { }

    CheckedOutputIter()
        : begin(), end() { }

    CheckedOutputIter(Iter begin, Iter end)
        : begin(begin), end(end) { }

    CheckedOutputIter& operator++() {
        // increment pas end?
        if (begin == end) {
            throw Sentinel();
        }

        ++begin;
        return *this;
    }

    CheckedOutputIter operator++(int) {
        // increment past end?
        if (begin == end) {
            throw Sentinel();
        }

        CheckedOutputIter tmp(*this);

        ++begin;

        return tmp;
    }

    typename iterator_traits<Iter>::value_type operator*() {
        return *begin;
    }


private:
    Iter begin, end;
};

Usage:

try {
    std::copy(begin1, end1, CheckedOutputIter(begin2, end2));
} catch(const CheckedOutputIter::Sentinel&) { }

This has roughly the same performance as your solution, but it is more widely usable.

like image 53
orlp Avatar answered Nov 07 '22 06:11

orlp