Skip to main content

std::ranges::uninitialized_copy() algorithm

// (1)
uninitialized_copy_result<I, O>
uninitialized_copy( I ifirst, S1 ilast, O ofirst, S2 olast );

// (2)
uninitialized_copy_result< ranges::borrowed_iterator_t<IR>,
ranges::borrowed_iterator_t<OR> >
uninitialized_copy( IR&& in_range, OR&& out_range );

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>>
  • (1) std::constructible_from<ranges::range_value_t<OR>, ranges::range_reference_t<IR>>

With the helper types defined as follows:

template< class I, class O >
using uninitialized_copy_result = ranges::in_out_result<I, O>;
  • (1) Let N be ranges::min(ranges::distance(ifirst, ilast), 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 [ifirst; ilast).

    important

    The input and output ranges must not overlap.

    caution

    If an exception is thrown during the initialization, the objects already constructed are destroyed in an unspecified order.

    The function has the effect equal to:

    for (; !(ifirst == ilast || ofirst == olast); ++ofirst, ++ifirst)
    {
    ::new (static_cast<void*>(std::addressof(*ofirst)))
    std::remove_reference_t<std::iter_reference_t<O>>(*ifirst);
    }
  • (2) Same as (1), but uses in_range as the first range and out_range as the second range, as if using ranges::begin(in_range) as ifirst, ranges::end(in_range) as ilast, ranges::begin(out_range) as ofirst, and ranges::end(out_range) as olast.

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

Parameters

ifirst
ilast

The range of elements to copy from.

in_range

The range of elements to copy from.

ofirst
olast

The destination range.

out_range

The destination range.

Return value

{
ifirst + N,
ofirst + N
}

Complexity

Given N as ranges::min(ranges::distance(ifirst, ilast), 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(1) and uninitialized_copy(2)
struct uninitialized_copy_fn
{
template<std::input_iterator I, std::sentinel_for<I> S1,
no-throw-forward-iterator O, no-throw-sentinel-for<O> S2>
requires std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>>
ranges::uninitialized_copy_result<I, O>
operator()(I ifirst, S1 ilast, O ofirst, S2 olast) const
{
O current{ofirst};
try
{
for (; !(ifirst == ilast or current == olast); ++ifirst, ++current)
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;
}
}

template<ranges::input_range IR, no-throw-forward-range OR>
requires std::constructible_from<ranges::range_value_t<OR>,
ranges::range_reference_t<IR>>
ranges::uninitialized_copy_result<ranges::borrowed_iterator_t<IR>,
ranges::borrowed_iterator_t<OR>>
operator()(IR&& in_range, OR&& out_range) const
{
return (*this)(ranges::begin(in_range), ranges::end(in_range),
ranges::begin(out_range), ranges::end(out_range));
}
};

inline constexpr uninitialized_copy_fn uninitialized_copy{};

Notes

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

Examples

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

int main()
{
const char* v[]{ "This", "is", "an", "example", };

if (const auto sz{std::size(v)};
void* pbuf = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
{
try
{
auto first {static_cast<std::string*>(pbuf)};
auto last {first + sz};
std::ranges::uninitialized_copy(std::begin(v), std::end(v), first, last);

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

std::ranges::destroy(first, last);
}
catch (...)
{
std::cout << "uninitialized_copy exception\n";
}
std::free(pbuf);
}
}
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() algorithm

// (1)
uninitialized_copy_result<I, O>
uninitialized_copy( I ifirst, S1 ilast, O ofirst, S2 olast );

// (2)
uninitialized_copy_result< ranges::borrowed_iterator_t<IR>,
ranges::borrowed_iterator_t<OR> >
uninitialized_copy( IR&& in_range, OR&& out_range );

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>>
  • (1) std::constructible_from<ranges::range_value_t<OR>, ranges::range_reference_t<IR>>

With the helper types defined as follows:

template< class I, class O >
using uninitialized_copy_result = ranges::in_out_result<I, O>;
  • (1) Let N be ranges::min(ranges::distance(ifirst, ilast), 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 [ifirst; ilast).

    important

    The input and output ranges must not overlap.

    caution

    If an exception is thrown during the initialization, the objects already constructed are destroyed in an unspecified order.

    The function has the effect equal to:

    for (; !(ifirst == ilast || ofirst == olast); ++ofirst, ++ifirst)
    {
    ::new (static_cast<void*>(std::addressof(*ofirst)))
    std::remove_reference_t<std::iter_reference_t<O>>(*ifirst);
    }
  • (2) Same as (1), but uses in_range as the first range and out_range as the second range, as if using ranges::begin(in_range) as ifirst, ranges::end(in_range) as ilast, ranges::begin(out_range) as ofirst, and ranges::end(out_range) as olast.

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

Parameters

ifirst
ilast

The range of elements to copy from.

in_range

The range of elements to copy from.

ofirst
olast

The destination range.

out_range

The destination range.

Return value

{
ifirst + N,
ofirst + N
}

Complexity

Given N as ranges::min(ranges::distance(ifirst, ilast), 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(1) and uninitialized_copy(2)
struct uninitialized_copy_fn
{
template<std::input_iterator I, std::sentinel_for<I> S1,
no-throw-forward-iterator O, no-throw-sentinel-for<O> S2>
requires std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>>
ranges::uninitialized_copy_result<I, O>
operator()(I ifirst, S1 ilast, O ofirst, S2 olast) const
{
O current{ofirst};
try
{
for (; !(ifirst == ilast or current == olast); ++ifirst, ++current)
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;
}
}

template<ranges::input_range IR, no-throw-forward-range OR>
requires std::constructible_from<ranges::range_value_t<OR>,
ranges::range_reference_t<IR>>
ranges::uninitialized_copy_result<ranges::borrowed_iterator_t<IR>,
ranges::borrowed_iterator_t<OR>>
operator()(IR&& in_range, OR&& out_range) const
{
return (*this)(ranges::begin(in_range), ranges::end(in_range),
ranges::begin(out_range), ranges::end(out_range));
}
};

inline constexpr uninitialized_copy_fn uninitialized_copy{};

Notes

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

Examples

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

int main()
{
const char* v[]{ "This", "is", "an", "example", };

if (const auto sz{std::size(v)};
void* pbuf = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
{
try
{
auto first {static_cast<std::string*>(pbuf)};
auto last {first + sz};
std::ranges::uninitialized_copy(std::begin(v), std::end(v), first, last);

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

std::ranges::destroy(first, last);
}
catch (...)
{
std::cout << "uninitialized_copy exception\n";
}
std::free(pbuf);
}
}
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.