std::ranges::copy_n() algorithm
- od C++20
- Simplified
- Detailed
// (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>
// (1)
template<
std::input_iterator I,
std::weakly_incrementable O
>
requires std::indirectly_copyable<I, O>
constexpr copy_n_result<I, O> copy_n( I first, std::iter_difference_t<I> n, O result );
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 atfirst
to the range beginning atresult
by performing*(result + i) = *(first + i)
for each integer in [0
;n
).
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 toranges::next(first, n)
- and a
std::weakly_incrementable
iterator equal toranges::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
#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';
}
"ABCD"
*(res.in): 'F', distance: 5
*(res.out): 'f', distance: 5
Hover to see the original license.