Skip to main content

std::ranges::copy() algorithm

// (1)
constexpr copy_result<I, O> copy( I first, S last, O result );

// (2)
constexpr copy_result<ranges::borrowed_iterator_t<R>, O> copy( R&& r, O result );

The type of arguments are generic and have following constraints:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • O - std::weakly_incrementable
  • (2) - R - std::ranges::input_range

With the helper types defined as follows:

template< class I, class O >
using copy_result = ranges::in_out_result<I, O>;

Copies the elements in the range, defined by [first; last), to another range beginning at result.

  • (1) Copies all elements in the range [first; last) starting from first and proceeding to last - 1.

    Undefined Behaviour

    The behavior is undefined if result is within the range [first; last). In this case, ranges::copy_backward may be used instead.

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

The function-like entities described on this page are niebloids.

Parameters

first
last

The range of elements to copy.

r

The range of elements to copy.

result

The beginning of the destination range.

Return value

A ranges::in_out_result containing an input iterator equal to last and an output iterator past the last element copied.

Complexity

Exactly last - first assignments.

Exceptions

(none)

Possible implementation

copy(1) and copy(2)
struct copy_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::copy_result<I, O> operator()(I first, S last, O result) const
{
for (; first != last; ++first, (void)++result)
*result = *first;
return {std::move(first), std::move(result)};
}

template<ranges::input_range R, std::weakly_incrementable O>
requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr ranges::copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
}
};

inline constexpr copy_fn copy;

Notes

In practice, implementations of ranges::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable and the iterator types satisfy contiguous_iterator.

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

Examples

The following code uses ranges::copy to both copy the contents of one std::vector to another and to display the resulting std::vector:

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

int main()
{
std::vector<int> source(10);
std::iota(source.begin(), source.end(), 0);

std::vector<int> destination;

std::ranges::copy(source.begin(), source.end(),
std::back_inserter(destination));
// or, alternatively,
// std::vector<int> destination(source.size());
// std::ranges::copy(source.begin(), source.end(), destination.begin());
// either way is equivalent to
// std::vector<int> destination = source;

std::cout << "destination contains: ";

std::ranges::copy(destination, std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';

std::cout << "odd numbers in destination are: ";

std::ranges::copy_if(destination, std::ostream_iterator<int>(std::cout, " "),
[](int x) { return (x % 2) == 1; });
std::cout << '\n';
}
Output
destination contains: 0 1 2 3 4 5 6 7 8 9
odd numbers in destination are: 1 3 5 7 9
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::ranges::copy() algorithm

// (1)
constexpr copy_result<I, O> copy( I first, S last, O result );

// (2)
constexpr copy_result<ranges::borrowed_iterator_t<R>, O> copy( R&& r, O result );

The type of arguments are generic and have following constraints:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • O - std::weakly_incrementable
  • (2) - R - std::ranges::input_range

With the helper types defined as follows:

template< class I, class O >
using copy_result = ranges::in_out_result<I, O>;

Copies the elements in the range, defined by [first; last), to another range beginning at result.

  • (1) Copies all elements in the range [first; last) starting from first and proceeding to last - 1.

    Undefined Behaviour

    The behavior is undefined if result is within the range [first; last). In this case, ranges::copy_backward may be used instead.

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

The function-like entities described on this page are niebloids.

Parameters

first
last

The range of elements to copy.

r

The range of elements to copy.

result

The beginning of the destination range.

Return value

A ranges::in_out_result containing an input iterator equal to last and an output iterator past the last element copied.

Complexity

Exactly last - first assignments.

Exceptions

(none)

Possible implementation

copy(1) and copy(2)
struct copy_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::copy_result<I, O> operator()(I first, S last, O result) const
{
for (; first != last; ++first, (void)++result)
*result = *first;
return {std::move(first), std::move(result)};
}

template<ranges::input_range R, std::weakly_incrementable O>
requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr ranges::copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
}
};

inline constexpr copy_fn copy;

Notes

In practice, implementations of ranges::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable and the iterator types satisfy contiguous_iterator.

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

Examples

The following code uses ranges::copy to both copy the contents of one std::vector to another and to display the resulting std::vector:

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

int main()
{
std::vector<int> source(10);
std::iota(source.begin(), source.end(), 0);

std::vector<int> destination;

std::ranges::copy(source.begin(), source.end(),
std::back_inserter(destination));
// or, alternatively,
// std::vector<int> destination(source.size());
// std::ranges::copy(source.begin(), source.end(), destination.begin());
// either way is equivalent to
// std::vector<int> destination = source;

std::cout << "destination contains: ";

std::ranges::copy(destination, std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';

std::cout << "odd numbers in destination are: ";

std::ranges::copy_if(destination, std::ostream_iterator<int>(std::cout, " "),
[](int x) { return (x % 2) == 1; });
std::cout << '\n';
}
Output
destination contains: 0 1 2 3 4 5 6 7 8 9
odd numbers in destination are: 1 3 5 7 9
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.