samedi 5 octobre 2019

std::copy, std::copy_backward and overlapping ranges

My references are to std::copy and std::copy_backward.

template< class InputIt, class OutputIt > OutputIt copy( InputIt first, InputIt last, OutputIt d_first );

Copies all elements in the range [first, last) starting from first and proceeding to last - 1. The behavior is undefined if d_first is within the range [first, last). In this case, std::copy_backward may be used instead.

template< class BidirIt1, class BidirIt2 > BidirIt2 copy_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last )

Copies the elements from the range, defined by [first, last), to another range ending at d_last. The elements are copied in reverse order (the last element is copied first), but their relative order is preserved.

The behavior is undefined if d_last is within (first, last]. std::copy must be used instead of std::copy_backward in that case.

When copying overlapping ranges, std::copy is appropriate when copying to the left (beginning of the destination range is outside the source range) while std::copy_backward is appropriate when copying to the right (end of the destination range is outside the source range).

From the above description, I gather the following inference:

Both copy and copy_backward end up copying the same source range [first, last) to the destination range, albeit in the case of the former the copying occurs from first to last - 1, whereas in the case of the latter the copying occurs from last -1 to first. In both cases, relative order of elements in the source range is preserved in the resulting destination range.

However, the following is not clear to me:

In the case of copy, undefined behavior results (implying unsuccessful copying of the source range to the destination range and possibly system fault) if d_first is within the range [first, last).

In the case of copy_backward, undefined behavior results (implying unsuccessful copying of the source range to the destination range and possibly system fault) if d_last is within the range (first, last].

I am assuming that the suggestion to replace copy with copy_backward to avert the above undefined behavior scenario, would become evident to me once I understand the implication of the above two statements.

Likewise, I am also assuming that the mention about the appropriateness of copy when copying to the left (which notion is not clear to me), and copy_backward when copying to the right (which notion is not clear to me either), would begin to make sense once I comprehend the above distinction between copy and copy_backward.

Look forward to your helpful thoughts as always.

Aucun commentaire:

Enregistrer un commentaire