Skip to main content

std::ranges::copy_n() algorithm

// (1)
constexpr copy_n_result<I, O>
copy_n( I first, std::iter_difference_t<I> n, O result );

The type of arguments are generic and have following constraints:

  • I - std::input_iterator
  • O - std::weakly_incrementable

Additionally, (1) has the following constraints:

  • std::indirectly_copyable<I, O>

With the helper types defined as follows:

template< class I, class O >
using copy_n_result = ranges::in_out_result<I, O>;
  • (1) Copies exactly n values from the range beginning at first to the range beginning at result by performing *(result + i) = *(first + i) for each integer in [0; n).
Undefined Behaviour

The behavior is undefined if result is within the range [first; first + n) (ranges::copy_backward might be used instead in this case).

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

Parameters

first

The beginning of the range to copy from.

n

Number of elements to copy.

result

The beginning of the destination range.

Return value

An object of of type copy_n_result initialized as follows:

{
first + n,
result + n
}

or more formally, a value of type ranges::in_out_result that contains:

  • std::input_iterator iterator equal to ranges::next(first, n)
  • and a std::weakly_incrementable iterator equal to ranges::next(result, n)

Complexity

Exactly n assignments.

Exceptions

(none)

Possible implementation

copy_n(1)

struct copy_n_fn
{
template<std::input_iterator I, std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::copy_n_result<I, O>
operator()(I first, std::iter_difference_t<I> n, O result) const
{
for (std::iter_difference_t<I> i {}; i != n; ++i, ++first, ++result)
*result = *first;
return {std::move(first), std::move(result)};
}
};

inline constexpr copy_n_fn copy_n {};

Notes

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

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

Main.cpp
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <string_view>

int main()
{
const std::string_view in {"ABCDEFGH"};
std::string out;

std::ranges::copy_n(in.begin(), 4, std::back_inserter(out));
std::cout << std::quoted(out) << '\n';

out = "abcdefgh";
const auto res = std::ranges::copy_n(in.begin(), 5, out.begin());
std::cout
<< "*(res.in): '" << *(res.in) << "', distance: "
<< std::distance(std::begin(in), res.in) << '\n'
<< "*(res.out): '" << *(res.out) << "', distance: "
<< std::distance(std::begin(out), res.out) << '\n';
}
Output
"ABCD"
*(res.in): 'F', distance: 5
*(res.out): 'f', distance: 5
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_n() algorithm

// (1)
constexpr copy_n_result<I, O>
copy_n( I first, std::iter_difference_t<I> n, O result );

The type of arguments are generic and have following constraints:

  • I - std::input_iterator
  • O - std::weakly_incrementable

Additionally, (1) has the following constraints:

  • std::indirectly_copyable<I, O>

With the helper types defined as follows:

template< class I, class O >
using copy_n_result = ranges::in_out_result<I, O>;
  • (1) Copies exactly n values from the range beginning at first to the range beginning at result by performing *(result + i) = *(first + i) for each integer in [0; n).
Undefined Behaviour

The behavior is undefined if result is within the range [first; first + n) (ranges::copy_backward might be used instead in this case).

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

Parameters

first

The beginning of the range to copy from.

n

Number of elements to copy.

result

The beginning of the destination range.

Return value

An object of of type copy_n_result initialized as follows:

{
first + n,
result + n
}

or more formally, a value of type ranges::in_out_result that contains:

  • std::input_iterator iterator equal to ranges::next(first, n)
  • and a std::weakly_incrementable iterator equal to ranges::next(result, n)

Complexity

Exactly n assignments.

Exceptions

(none)

Possible implementation

copy_n(1)

struct copy_n_fn
{
template<std::input_iterator I, std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::copy_n_result<I, O>
operator()(I first, std::iter_difference_t<I> n, O result) const
{
for (std::iter_difference_t<I> i {}; i != n; ++i, ++first, ++result)
*result = *first;
return {std::move(first), std::move(result)};
}
};

inline constexpr copy_n_fn copy_n {};

Notes

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

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

Main.cpp
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <string_view>

int main()
{
const std::string_view in {"ABCDEFGH"};
std::string out;

std::ranges::copy_n(in.begin(), 4, std::back_inserter(out));
std::cout << std::quoted(out) << '\n';

out = "abcdefgh";
const auto res = std::ranges::copy_n(in.begin(), 5, out.begin());
std::cout
<< "*(res.in): '" << *(res.in) << "', distance: "
<< std::distance(std::begin(in), res.in) << '\n'
<< "*(res.out): '" << *(res.out) << "', distance: "
<< std::distance(std::begin(out), res.out) << '\n';
}
Output
"ABCD"
*(res.in): 'F', distance: 5
*(res.out): 'f', distance: 5
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.