Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/memory/uninitialized move"

From cppreference.com
< cpp‎ | memory
m ({{range}}, {{c}}, fmt)
(~)
 
(One intermediate revision by one user not shown)
Line 15: Line 15:
 
{{dcl end}}
 
{{dcl end}}
  
@1@ Moves elements from the range {{range|first|last}} to an uninitialized memory area beginning at {{c|d_first}} as if by  
+
@1@ Moves elements from the range {{range|first|last}} to an uninitialized memory area beginning at {{c|d_first}} as if by<br>
{{source|1=
+
{{c multi|
for (; first != last; ++d_first, (void) ++first)
+
for (; first !{{=}} last; ++d_first, (void) ++first)|
     ::new (static_cast<void*>(std::addressof(*d_first)))
+
     ::new (static_cast<void*>(std::addressof(*d_first)))|
 
         typename std::iterator_traits<NoThrowForwardIt>::value_type(std::move(*first));
 
         typename std::iterator_traits<NoThrowForwardIt>::value_type(std::move(*first));
 
}}
 
}}
  
 
@@ If an exception is thrown during the initialization, some objects in {{range|first|last}} are left in a valid but unspecified state, and the objects already constructed are destroyed in an unspecified order.
 
@@ If an exception is thrown during the initialization, some objects in {{range|first|last}} are left in a valid but unspecified state, and the objects already constructed are destroyed in an unspecified order.
 +
{{rrev|since=c++20|
 +
If {{counted range|d_first|std::distance(first, last)}} overlaps with {{range|first|last}}, the behavior is undefined.
 +
}}
  
 
@2@ Same as {{v|1}}, but executed according to {{c|policy}}. {{cpp/algorithm/parallel overload precondition}}
 
@2@ Same as {{v|1}}, but executed according to {{c|policy}}. {{cpp/algorithm/parallel overload precondition}}
Line 45: Line 48:
  
 
===Exceptions===
 
===Exceptions===
{{cpp/algorithm/parallel_exceptions_reporting_behavior|singular=yes}}
+
{{cpp/algorithm/parallel exceptions reporting behavior|singular=yes}}
  
 
===Possible implementation===
 
===Possible implementation===
Line 87: Line 90:
 
     std::string in[]{"Home", "Work!"};
 
     std::string in[]{"Home", "Work!"};
 
     print("initially, in: ", std::begin(in), std::end(in));
 
     print("initially, in: ", std::begin(in), std::end(in));
 
+
   
 
     if (
 
     if (
 
         constexpr auto sz = std::size(in);
 
         constexpr auto sz = std::size(in);
Line 97: Line 100:
 
             auto last{first + sz};
 
             auto last{first + sz};
 
             std::uninitialized_move(std::begin(in), std::end(in), first);
 
             std::uninitialized_move(std::begin(in), std::end(in), first);
 
+
           
 
             print("after move, in: ", std::begin(in), std::end(in));
 
             print("after move, in: ", std::begin(in), std::end(in));
 
             print("after move, out: ", first, last);
 
             print("after move, out: ", first, last);
 
+
           
 
             std::destroy(first, last);
 
             std::destroy(first, last);
 
         }
 
         }
Line 119: Line 122:
 
===Defect reports===
 
===Defect reports===
 
{{dr list begin}}
 
{{dr list begin}}
{{dr list item|wg=lwg|dr=3870|std=C++20|before=this algorithm might create objects on a {{c|const}} storage|after=kept disallowed}}
+
{{dr list item|wg=lwg|dr=3870|std=C++20|before=this algorithm might create objects on a {{c/core|const}} storage|after=kept disallowed}}
 
{{dr list end}}
 
{{dr list end}}
  

Latest revision as of 19:02, 25 July 2023

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
Dynamic memory management
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Allocators
Garbage collection support
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)



 
Defined in header <memory>
template< class InputIt, class NoThrowForwardIt >

NoThrowForwardIt uninitialized_move( InputIt first, InputIt last,

                                     NoThrowForwardIt d_first );
(1) (since C++17)
template< class ExecutionPolicy, class ForwardIt, class NoThrowForwardIt >

NoThrowForwardIt uninitialized_move( ExecutionPolicy&& policy,
                                     ForwardIt first, ForwardIt last,

                                     NoThrowForwardIt d_first );
(2) (since C++17)
1) Moves elements from the range [firstlast) to an uninitialized memory area beginning at d_first as if by
for (; first != last; ++d_first, (void) ++first)
    ::new (static_cast<void*>(std::addressof(*d_first)))
        typename std::iterator_traits<NoThrowForwardIt>::value_type(std::move(*first));
If an exception is thrown during the initialization, some objects in [firstlast) are left in a valid but unspecified state, and the objects already constructed are destroyed in an unspecified order.

If d_first + [0std::distance(first, last)) overlaps with [firstlast), the behavior is undefined.

(since C++20)
2) Same as (1), but executed according to policy. This overload participates in overload resolution only if

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> is true.

(until C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> is true.

(since C++20)

Contents

[edit] Parameters

first, last - the range of the elements to move
d_first - the beginning of the destination range
policy - the execution policy to use. See execution policy for details.
Type requirements
-
InputIt must meet the requirements of LegacyInputIterator.
-
ForwardIt must meet the requirements of LegacyForwardIterator.
-
NoThrowForwardIt must meet the requirements of LegacyForwardIterator.
-
No increment, assignment, comparison, or indirection through valid instances of NoThrowForwardIt may throw exceptions.

[edit] Return value

Iterator to the element past the last element moved.

[edit] Complexity

Linear in the distance between first and last.

[edit] Exceptions

The overload with a template parameter named ExecutionPolicy reports errors as follows:

  • If execution of a function invoked as part of the algorithm throws an exception and ExecutionPolicy is one of the standard policies, std::terminate is called. For any other ExecutionPolicy, the behavior is implementation-defined.
  • If the algorithm fails to allocate memory, std::bad_alloc is thrown.

[edit] Possible implementation

template<class InputIt, class NoThrowForwardIt>
NoThrowForwardIt uninitialized_move(InputIt first, InputIt last, NoThrowForwardIt d_first)
{
    using Value = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    NoThrowForwardIt current = d_first;
    try
    {
        for (; first != last; ++first, (void) ++current)
            ::new (static_cast<void*>(std::addressof(*current))) Value(std::move(*first));
        return current;
    }
    catch (...)
    {
        std::destroy(d_first, current);
        throw;
    }
}

[edit] Example

#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
 
void print(auto rem, auto first, auto last)
{
    for (std::cout << rem; first != last; ++first)
        std::cout << std::quoted(*first) << ' ';
    std::cout << '\n';
}
 
int main()
{
    std::string in[]{"Home", "Work!"};
    print("initially, in: ", std::begin(in), std::end(in));
 
    if (
        constexpr auto sz = std::size(in);
        void* out = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
    {
        try
        {
            auto first{static_cast<std::string*>(out)};
            auto last{first + sz};
            std::uninitialized_move(std::begin(in), std::end(in), first);
 
            print("after move, in: ", std::begin(in), std::end(in));
            print("after move, out: ", first, last);
 
            std::destroy(first, last);
        }
        catch (...)
        {
            std::cout << "Exception!\n";
        }
        std::free(out);
    }
}

Possible output:

initially, in: "Home" "Work!"
after move, in: "" ""
after move, out: "Home" "Work!"

[edit] Defect reports

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

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

[edit] See also

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