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;
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With