std::ranges...copy_result(3)
std::ranges::uninitialized_copy, std::ranges::uninitialized_copy_result π
from the C++ Standard Library manual, page std::ranges...copy_result(3) β okay bestie, this one is lowkey iconic and we are getting into it π
π NAME π
It's std::ranges::uninitialized_copy, std::ranges::uninitialized_copy_result β yes, both of them, exactly like the manual's NAME line says:
std::ranges::uninitialized_copy,std::ranges::uninitialized_copy_result - std::ranges::uninitialized_copy,std::ranges::uninitialized_copy_result
β¨ Synopsis β¨
Defined in header <memory> π«Ά
Call signature π«
(1) β since C++20
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) β since C++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 );
Helper types π§
(3) β since C++20
template< class I, class O >
using uninitialized_copy_result = ranges::in_out_result<I, O>;
So (1) is giving: let N be ranges::min(ranges::distance(ifirst, ilast), ranges::distance(ofirst, olast)). It constructs N elements in the output range [ofirst, olast) β which is an uninitialized memory area β from the elements in the input range [ifirst, ilast). 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) is 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. Slay π
The function-like entities described on this page are niebloids, that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
In practice, they may be implemented as function objects, or with special compiler extensions. iykyk β¨
πΈ Parameters πΈ
ifirst,ilastβ iterator-sentinel pair denoting the range of elements to copy fromin_rangeβ the range of elements to copy fromofirst,olastβ iterator-sentinel pair denoting the destination rangeout_rangeβ the destination range
π¦ Return value π¦
{ifirst + N, ofirst + N}
That's the whole vibe, bestie π«Ά
π₯ Complexity π₯
\(\scriptsize\mathcal{O}(N)\)π(N).
Literally linear time, periodt π
π Exceptions π
The exception thrown on construction of the elements in the destination range, if any. Not me being dramatic, but if it throws, it throws π
β Notes β
An implementation may improve the efficiency of ranges::uninitialized_copy if the value type of the output range is TrivialType. Nice little optimization moment π
π 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 π
// Run this code
#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"};
Ate and left no crumbs π
π Defect reports π
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
- LWG 3870 β applied to C++20. Behavior as published:
this algorithm might create objects on a const storage. Correct behavior:kept disallowed. The way that got handled π
π See also π
ranges::uninitialized_copy_n(C++20) β copies a number of objects to an uninitialized area of memory (niebloid)uninitialized_copyβ copies a range of objects to an uninitialized area of memory (function template)
That's the whole page, bestie π Source: http://cppreference.com β version/date: 2024.06.10 β manual: std::ranges...copy_result(3). Now go construct those objects and live your main character era π§ββοΈπ
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms