Skip to main content

std::ranges::uninitialized_copy_n() algorithm

// (1)
uninitialized_copy_n_result<I, O>
uninitialized_copy_n( I ifirst, std::iter_difference_t<I> count, O ofirst, S olast );

The type of arguments are generic and have following constraints:

Additionally, each overload has the following constraints:

  • (1) std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>>

With the helper types defined as follows:

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

Let N be ranges::min(count, ranges::distance(ofirst, olast)), constructs N elements in the output range [ofirst; olast), which is an uninitialized memory area, from the elements in the input range beginning at ifirst.

The input range [ifirst; ifirst + count) must not overlap with the output range [ofirst; olast).

The function has the effect equivalent to:

auto ret = ranges::uninitialized_copy(std::counted_iterator(ifirst, count),
std::default_sentinel, ofirst, olast);
return {std::move(ret.in).base(), ret.out};

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

Parameters

ifirst

The begnning of the range of elements to copy from.

count

The number of elements to copy.

ofirst
olast

The destination range.

out_range

The destination range.

Return value

{
ifirst + N,
ofirst + N
}

Complexity

Given N as ranges::min(count, ranges::distance(ofirst, olast)):

O(N)

Exceptions

The exception thrown on construction of the elements in the destination range, if any.

Possible implementation

uninitialized_copy_n(1)
struct uninitialized_copy_n_fn
{
template<std::input_iterator I, no-throw-input-iterator O, no-throw-sentinel-for<O> S>
requires std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>>
ranges::uninitialized_copy_n_result<I, O>
operator()(I ifirst, std::iter_difference_t<I> count, O ofirst, S olast) const
{
O current{ofirst};
try
{
for (; count > 0 && current != olast; ++ifirst, ++current, --count)
ranges::construct_at(std::addressof(*current), *ifirst);
return {std::move(ifirst), std::move(current)};
}
catch (...) // rollback: destroy constructed elements
{
for (; ofirst != current; ++ofirst)
ranges::destroy_at(std::addressof(*ofirst));
throw;
}
}
};

inline constexpr uninitialized_copy_n_fn uninitialized_copy_n{};

Notes

An implementation may improve the efficiency of ranges::uninitialized_copy_n if the value type of the output range is TrivialType.

Examples

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

Main.cpp
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>

int main()
{
const char* stars[]{ "Procyon", "Spica", "Pollux", "Deneb", "Polaris", };

constexpr int n{4};
alignas(alignof(std::string)) char out[n * sizeof(std::string)];

try
{
auto first{reinterpret_cast<std::string*>(out)};
auto last{first + n};
auto ret{std::ranges::uninitialized_copy_n(std::begin(stars), n, first, last)};

std::cout << "{ ";
for (auto it{first}; it != ret.out; ++it)
std::cout << std::quoted(*it) << ", ";
std::cout << "};\n";

std::ranges::destroy(first, last);
}
catch (...)
{
std::cout << "uninitialized_copy_n exception\n";
}
}
Output
{ "This", "is", "an", "example", };
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::uninitialized_copy_n() algorithm

// (1)
uninitialized_copy_n_result<I, O>
uninitialized_copy_n( I ifirst, std::iter_difference_t<I> count, O ofirst, S olast );

The type of arguments are generic and have following constraints:

Additionally, each overload has the following constraints:

  • (1) std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>>

With the helper types defined as follows:

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

Let N be ranges::min(count, ranges::distance(ofirst, olast)), constructs N elements in the output range [ofirst; olast), which is an uninitialized memory area, from the elements in the input range beginning at ifirst.

The input range [ifirst; ifirst + count) must not overlap with the output range [ofirst; olast).

The function has the effect equivalent to:

auto ret = ranges::uninitialized_copy(std::counted_iterator(ifirst, count),
std::default_sentinel, ofirst, olast);
return {std::move(ret.in).base(), ret.out};

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

Parameters

ifirst

The begnning of the range of elements to copy from.

count

The number of elements to copy.

ofirst
olast

The destination range.

out_range

The destination range.

Return value

{
ifirst + N,
ofirst + N
}

Complexity

Given N as ranges::min(count, ranges::distance(ofirst, olast)):

O(N)

Exceptions

The exception thrown on construction of the elements in the destination range, if any.

Possible implementation

uninitialized_copy_n(1)
struct uninitialized_copy_n_fn
{
template<std::input_iterator I, no-throw-input-iterator O, no-throw-sentinel-for<O> S>
requires std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>>
ranges::uninitialized_copy_n_result<I, O>
operator()(I ifirst, std::iter_difference_t<I> count, O ofirst, S olast) const
{
O current{ofirst};
try
{
for (; count > 0 && current != olast; ++ifirst, ++current, --count)
ranges::construct_at(std::addressof(*current), *ifirst);
return {std::move(ifirst), std::move(current)};
}
catch (...) // rollback: destroy constructed elements
{
for (; ofirst != current; ++ofirst)
ranges::destroy_at(std::addressof(*ofirst));
throw;
}
}
};

inline constexpr uninitialized_copy_n_fn uninitialized_copy_n{};

Notes

An implementation may improve the efficiency of ranges::uninitialized_copy_n if the value type of the output range is TrivialType.

Examples

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

Main.cpp
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>

int main()
{
const char* stars[]{ "Procyon", "Spica", "Pollux", "Deneb", "Polaris", };

constexpr int n{4};
alignas(alignof(std::string)) char out[n * sizeof(std::string)];

try
{
auto first{reinterpret_cast<std::string*>(out)};
auto last{first + n};
auto ret{std::ranges::uninitialized_copy_n(std::begin(stars), n, first, last)};

std::cout << "{ ";
for (auto it{first}; it != ret.out; ++it)
std::cout << std::quoted(*it) << ", ";
std::cout << "};\n";

std::ranges::destroy(first, last);
}
catch (...)
{
std::cout << "uninitialized_copy_n exception\n";
}
}
Output
{ "This", "is", "an", "example", };
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.