std::ranges::uninitialized_copy() algorithm
- od C++20
- Simplified
- Detailed
// (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:
I-std::input_iteratorS1,S2-std::sentinel_for<I>,no-throw-sentinel-for<O>O-no-throw-forward-iteratorIR-ranges::input_rangeOR-no-throw-forward-range
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>>
// (1)
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>>
uninitialized_copy_result<I, O>
uninitialized_copy( I ifirst, S1 ilast, O ofirst, S2 olast );
// (2)
template<
ranges::input_range IR,
no-throw-forward-range OR
>
requires std::constructible_from<ranges::range_value_t<OR>,
ranges::range_reference_t<IR>>
uninitialized_copy_result< ranges::borrowed_iterator_t<IR>,
ranges::borrowed_iterator_t<OR> >
uninitialized_copy( IR&& in_range, OR&& out_range );
With the helper types defined as follows:
template< class I, class O >
using uninitialized_copy_result = ranges::in_out_result<I, O>;
-
(1) Let
Nberanges::min(ranges::distance(ifirst, ilast), ranges::distance(ofirst, olast)): ConstructsNelements in the output range [ofirst;olast), which is an uninitialized memory area, from the elements in the input range [ifirst;ilast).importantThe input and output ranges must not overlap.
uwagaIf 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_rangeas the first range andout_rangeas the second range, as if usingranges::begin(in_range)asifirst,ranges::end(in_range)asilast,ranges::begin(out_range)asofirst, andranges::end(out_range)asolast.
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)
Notes
An implementation may improve the efficiency of ranges::uninitialized_copy if the value type of the output range is TrivialType.
Examples
#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);
}
}
{ "This", "is", "an", "example", };
Hover to see the original license.