Namespaces
Variants

std::ranges::move, std::ranges::move_result

From cppreference.com
 
 
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Non-modifying sequence operations    
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17)(C++11)
(C++20)(C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
(C++11)    

Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
(C++11)
(C++17)
Lexicographical comparison operations
Permutation operations


 
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Fold operations (Helper templates)
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
       
       
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
       
       
Permutation operations
Specialized <memory> algorithms
Return types
 
Defined in header <algorithm>
Call signature
template< std::input_iterator I, std::sentinel_for<I> S,
          std::weakly_incrementable O >
    requires std::indirectly_movable<I, O>
constexpr ranges::move_result<I, O>
    move( I first, S last, O d_first );
(1) (since C++20)
template< ranges::input_range R, std::weakly_incrementable O >
    requires std::indirectly_movable<ranges::iterator_t<R>, O>
constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O>
    move( R&& r, O d_first );
(2) (since C++20)
template< /*execution-policy*/ Ep,
          std::random_access_iterator I, std::sized_sentinel_for<I> S,
          std::random_access_iterator O, std::sized_sentinel_for<O> OutS >
    requires std::indirectly_movable<I, O>
ranges::move_result<I, O>
    move( Ep&& policy, I first, S last, O d_first, OutS d_last );
(3) (since C++26)
template< /*execution-policy*/ Ep,
          /*sized-random-access-range*/ R, /*sized-random-access-range*/ OutR >
    requires std::indirectly_movable<ranges::iterator_t<R>,
                                     ranges::iterator_t<OutR>>
ranges::move_result<ranges::borrowed_iterator_t<R>,
                    ranges::borrowed_iterator_t<OutR>>
    move( Ep&& policy, R&& r, OutR&& d_r );
(4) (since C++26)
Helper types
template< class I, class O >
using move_result = ranges::in_out_result<I, O>;
(5) (since C++20)

For the definition of /*execution-policy*/, see this page; for the definition of /*sized-random-access-range*/, see this page.

Moves the elements in the source range [firstlast) or r to the destination range.

1,2) Moves all elements in the source range, starting from the beginning and proceeding to the end.
1) The destination range is [d_firstranges::next(d_first, ranges::distance(first, last))).
2) The destination range is [d_firstranges::next(d_first, ranges::distance(r))).
If d_first is in the source range, the behavior is undefined.
3,4) Same as (1,2), but the move order is determined by policy. If the destination range is exhausted before reaching the end of the source range, the remaining elements in the source range will not be moved.
3) The destination range is [d_firstd_last).
4) The destination range is d_r.
If the source and destination ranges overlap, the behavior is undefined.

The function-like entities described on this page are algorithm function objects (informally known as niebloids), that is:

Parameters

first, last - the iterator-sentinel pair defining the source range
r - the source range
d_first - the beginning of the destination range
d_last - the sentinel of the destination range
d_r - the destination range
policy - the execution policy to use

Return value

A ranges::move_result object where:

  • The data member in holds the an iterator past the last moved element in the source range, or an iterator to the beginning of the source range if no element is moved.
  • The data member out holds and an iterator past the last move-assigned element in the destination range, or an iterator to the beginning of the destination range if no element is moved.

Complexity

Given

  • N1 as ranges::distance(first, last) or ranges::distance(r), and
  • N2 as ranges::distance(d_first, d_last) or ranges::distance(d_r):
1,2) Exactly N1 assignments.
3,4) Exactly min(N1,N2) assignments.

Exceptions

3,4) During the execution process:
  • If the temporary memory resources required for parallelization are not available, std::bad_alloc is thrown.
  • If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for standard policies, std::terminate is invoked).

Notes

When moving overlapping ranges, ranges::move is appropriate when moving to the left (beginning of the destination range is outside the source range) while ranges::move_backward is appropriate when moving to the right (end of the destination range is outside the source range).

Possible implementation

struct move_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
        requires std::indirectly_movable<I, O>
    constexpr ranges::move_result<I, O>
        operator()(I first, S last, O result) const
    {
        for (; first != last; ++first, ++result)
            *result = ranges::iter_move(first);
        return {std::move(first), std::move(result)};
    }
    
    template<ranges::input_range R, std::weakly_incrementable O>
        requires std::indirectly_movable<ranges::iterator_t<R>, O>
    constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O result) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
    }
    
    template<ranges::forward_range R, std::weakly_incrementable O>
        requires std::indirectly_movable<ranges::iterator_t<R>, O>
    constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O result) const
    {
        return (*this)(ranges::begin(r),
                       ranges::next(ranges::begin(r), ranges::end(r)),
                       std::move(result));
    }
};

inline constexpr move_fn move{};

Example

The following code moves thread objects (which themselves are not copyable) from one container to another.

#include <algorithm>
#include <chrono>
#include <iostream>
#include <iterator>
#include <list>
#include <thread>
#include <vector>

using namespace std::literals::chrono_literals;

void f(std::chrono::milliseconds n)
{
    std::this_thread::sleep_for(n);
    std::cout << "thread with n=" << n.count() << "ms ended" << std::endl;
}

int main()
{
    std::vector<std::jthread> v;
    v.emplace_back(f, 400ms);
    v.emplace_back(f, 600ms);
    v.emplace_back(f, 800ms);
    
    std::list<std::jthread> l;
    
    // std::ranges::copy() would not compile, because std::jthread is non-copyable
    std::ranges::move(v, std::back_inserter(l));
}

Output:

thread with n=400ms ended
thread with n=600ms ended
thread with n=800ms ended

See also

(C++11)
moves a range of elements to a new location
(function template) [edit]
moves a range of elements to a new location in backwards order
(algorithm function object)[edit]
copies a range of elements to a new location
(algorithm function object)[edit]
copies a range of elements in backwards order
(algorithm function object)[edit]
(C++11)
converts the argument to an xvalue
(function template) [edit]