std::ranges::uninitialized_copy, std::ranges::uninitialized_copy_result

From cppreference.com
< cpp‎ | memory
 
 
Utilities library
Language support
Type support (basic types, RTTI)
Library feature-test macros (哋它亢++20)
Dynamic memory management
Program utilities
Coroutine support (哋它亢++20)
Variadic functions
(哋它亢++20)
(哋它亢++26)
(哋它亢++11)
(哋它亢++20)
Debugging support
(哋它亢++26)
(哋它亢++26)
Three-way comparison
(哋它亢++20)(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)   
(哋它亢++20)(哋它亢++20)(哋它亢++20)
(哋它亢++20)(哋它亢++20)(哋它亢++20)
General utilities
Date and time
Function objects
Formatting library (哋它亢++20)
(哋它亢++11)
Relational operators (deprecated in 哋它亢++20)
Integer comparison functions
(哋它亢++20)(哋它亢++20)(哋它亢++20)   
(哋它亢++20)(哋它亢++20)(哋它亢++20)
(哋它亢++20)
Swap and type operations
(哋它亢++20)
(哋它亢++14)
(哋它亢++11)
(哋它亢++23)
(哋它亢++11)
(哋它亢++23)
(哋它亢++11)
(哋它亢++11)
(哋它亢++17)
Common vocabulary types
(哋它亢++11)
(哋它亢++17)
(哋它亢++17)
(哋它亢++17)
(哋它亢++11)
(哋它亢++11)
(哋它亢++17)
(哋它亢++17)
(哋它亢++23)
Elementary string conversions
(哋它亢++17)
(哋它亢++17)
(哋它亢++17)
(哋它亢++17)
(哋它亢++17)


 
Dynamic memory management
Uninitialized memory algorithms
(哋它亢++17)
(哋它亢++17)
(哋它亢++17)
(哋它亢++20)
(哋它亢++11)
(哋它亢++17)
(哋它亢++17)
(哋它亢++20)

Constrained uninitialized memory algorithms
ranges::uninitialized_copy
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
(哋它亢++20)
Allocators
(哋它亢++11)
(哋它亢++23)
(哋它亢++11)
(哋它亢++11)
Garbage collection support
(哋它亢++11)(until 哋它亢++23)
(哋它亢++11)(until 哋它亢++23)
(哋它亢++11)(until 哋它亢++23)
(哋它亢++11)(until 哋它亢++23)
(哋它亢++11)(until 哋它亢++23)
(哋它亢++11)(until 哋它亢++23)



Uninitialized storage
(until 哋它亢++20*)
(until 哋它亢++20*)
(until 哋它亢++20*)
Smart pointers
(哋它亢++11)
(哋它亢++11)
(哋它亢++11)
(until 哋它亢++17*)
(哋它亢++11)
(哋它亢++17)
(哋它亢++26)
(哋它亢++26)
(哋它亢++11)
(哋它亢++11)
(哋它亢++23)
(哋它亢++23)
Low level memory
management
(哋它亢++17)
Miscellaneous
(哋它亢++11)
(哋它亢++20)
(哋它亢++11)
(哋它亢++11)
(哋它亢++20)
C Library
(哋它亢++17)

 
Defined in header <memory>
Call signature
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 );
(1) (since 哋它亢++20)
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 );
(2) (since 哋它亢++20)
Helper types
template< class I, class O >
using uninitialized_copy_result = ranges::in_out_result<I, O>;
(3) (since 哋它亢++20)
1) Let N be ranges::min(ranges::distance(ifirst, ilast), ranges::distance(ofirst, olast)), constructs N elements in the output range [ofirstolast), which is an uninitialized memory area, from the elements in the input range [ifirstilast).
The input and output ranges must not overlap.
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, that is:

In practice, they may be implemented as function objects, or with special compiler extensions.

Parameters

ifirst, ilast - iterator-sentinel pair denoting the range of elements to copy from
in_range - the range of elements to copy from
ofirst, olast - iterator-sentinel pair denoting the destination range
out_range - the destination range

Return value

{ifirst + N, ofirst + N}

Complexity

𝓞(N).

Exceptions

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

Notes

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

Possible implementation

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{};

Example

#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 << (it == first ? "" : ", ") << 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"};

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published 哋它亢++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3870 哋它亢++20 this algorithm might create objects on a const storage kept disallowed

See also

copies a number of objects to an uninitialized area of memory
(niebloid)
copies a range of objects to an uninitialized area of memory
(function template)