Spec-Zone.ru › C++

std::ranges::copy, std::ranges::copy_if, std::ranges::copy_result, std::ranges::copy_if_result

Defined in header <algorithm>
Call signature
template< std::input_iterator I, std::sentinel_for<I> S,
          std::weakly_incrementable O >
    requires std::indirectly_copyable<I, O>
constexpr copy_result<I, O>
    copy( I first, S last, O d_first );
(1) (since C++20)
template< ranges::input_range R, std::weakly_incrementable O >
    requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr copy_result<ranges::borrowed_iterator_t<R>, O>
    copy( R&& r, O d_first );
(2) (since C++20)
template< std::input_iterator I, std::sentinel_for<I> S,
          std::weakly_incrementable O, class Proj = std::identity,
          std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
    requires std::indirectly_copyable<I, O>
constexpr copy_if_result<I, O>
    copy_if( I first, S last, O d_first, Pred pred, Proj proj = {} );
(3) (since C++20)
template< ranges::input_range R,
          std::weakly_incrementable O, class Proj = std::identity,
          std::indirect_unary_predicate
              <std::projected<ranges::iterator_t<R>, Proj>> Pred >
    requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr copy_if_result<ranges::borrowed_iterator_t<R>, O>
    copy_if( R&& r, O d_first, Pred pred, Proj proj = {} );
(4) (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_copyable<I, O>
copy_result<I, O>
    copy( Ep&& policy, I first, S last, O d_first, OutS d_last );
(5) (since C++26)
template< /*execution-policy*/ Ep,
          /*sized-random-access-range*/ R,
          /*sized-random-access-range*/ OutR >
    requires std::indirectly_copyable<ranges::iterator_t<R>,
                                      ranges::iterator_t<OutR>>
copy_result<ranges::borrowed_iterator_t<R>,
            ranges::borrowed_iterator_t<OutR>>
    copy( Ep&& policy, R&& r, OutR&& d_r );
(6) (since C++26)
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,
          class Proj = std::identity,
          std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
    requires std::indirectly_copyable<I, O>
copy_if_result<I, O>
    copy_if( Ep&& policy, I first, S last, O d_first, OutS d_last,
             Pred pred, Proj proj = {} );
(7) (since C++26)
template< /*execution-policy*/ Ep,
          /*sized-random-access-range*/ R,
          /*sized-random-access-range*/ OutR,
          class Proj = std::identity,
          std::indirect_unary_predicate
              <std::projected<ranges::iterator_t<R>, Proj>> Pred >
    requires std::indirectly_copyable<ranges::iterator_t<R>,
                                      ranges::iterator_t<OutR>>
copy_if_result<ranges::borrowed_iterator_t<R>,
               ranges::borrowed_iterator_t<OutR>>
    copy_if( Ep&& policy, R&& r, OutR&& d_r,
             Pred pred, Proj proj = {} );
(8) (since C++26)
Helper types
template< class I, class O >
using copy_result = ranges::in_out_result<I, O>;
(9) (since C++20)
template< class I, class O >
using copy_if_result = ranges::in_out_result<I, O>;
(10) (since C++20)

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

Copies the elements in the source range [first, last) or r to the destination range.

1,2) copy copies all elements in the source range, starting from the beginning and proceeding to the end. The destination range begins at d_first.
If d_first is in the source range, the behavior is undefined.
3,4) copy_if only copies the elements (projected by proj) for which the predicate pred returns true. The destination range begins at d_first.
If the source and destination ranges overlap, the behavior is undefined.
5-8) Same as (1-4), but the copy 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 copied.
If the source and destination ranges overlap, the behavior is undefined.
5,7) The destination range is [d_first, d_last).
6,8) The destination range is d_r.

The function-like entities described on this page are algorithm function objects (informally known as 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.

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
pred - the predicate to be applied to the (projected) elements
proj - the projection to be applied to the elements in the source range
policy - the execution policy to use

Return value

A ranges::copy_result or ranges::copy_if_result object where:

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

Complexity

Given

  • \(\scriptsize N_1\)N1 as ranges::distance(first, last) or ranges::distance(r), and
  • \(\scriptsize N_2\)N2 as ranges::distance(d_first, d_last) or ranges::distance(d_r):
1,2) Exactly \(\scriptsize N_1\)N1 assignments.
3,4) Exactly \(\scriptsize N_1\)N1 pred and proj, and at most \(\scriptsize N_1\)N1 assignments.
5,6) Exactly \(\scriptsize \min(N_1,N_2)\)min(N1,N2) assignments.
7,8) Exactly \(\scriptsize \min(N_1,N_2)\)min(N1,N2) pred and proj, and at most \(\scriptsize \min(N_1,N_2)\)min(N1,N2) assignments.

Exceptions

5-8) 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

In practice, implementations of ranges::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable and the iterator types satisfy contiguous_iterator.

When copying overlapping ranges, ranges::copy is appropriate when copying to the left (beginning of the destination range is outside the source range) while ranges::copy_backward is appropriate when copying to the right (end of the destination range is outside the source range).

ranges::copy_if is stable. The relative order of the elements that are copied is preserved.

For parallel algorithm overloads, there may be a performance cost if std::iter_value_t<I> or ranges::range_value_t<R> does not model move_constructible.

Possible implementation

copy
struct copy_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
        requires std::indirectly_copyable<I, O>
    constexpr ranges::copy_result<I, O> operator()(I first, S last, O d_first) const
    {
        for (; first != last; ++first, (void)++d_first)
            *d_first = *first;
        return {std::move(first), std::move(d_first)};
    }
    
    template<ranges::input_range R, std::weakly_incrementable O>
        requires std::indirectly_copyable<ranges::iterator_t<R>, O>
    constexpr ranges::copy_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O d_first) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(d_first));
    }
    
    template<ranges::forward_range R, std::weakly_incrementable O>
        requires std::indirectly_copyable<ranges::iterator_t<R>, O>
    constexpr ranges::copy_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O d_first) const
    {
        return (*this)(ranges::begin(r),
                       ranges::next(ranges::begin(r), ranges::end(r)),
                       std::move(d_first));
    }
};

inline constexpr copy_fn copy;
copy_if
struct copy_if_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_unary_predicate<std::projected<I, Proj>> Pred>
        requires std::indirectly_copyable<I, O>
    constexpr ranges::copy_if_result<I, O>
        operator()(I first, S last, O d_first, Pred pred, Proj proj = {}) const
    {
        for (; first != last; ++first)
            if (std::invoke(pred, std::invoke(proj, *first)))
            {
                *d_first = *first;
                ++d_first;
            }
        return {std::move(first), std::move(d_first)};
    }
    
    template<ranges::input_range R, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_unary_predicate
                 <std::projected<ranges::iterator_t<R>, Proj>> Pred>
        requires std::indirectly_copyable<ranges::iterator_t<R>, O>
    constexpr ranges::copy_if_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O d_first, Pred pred, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r),
                       std::move(d_first), std::ref(pred), std::ref(proj));
    }
    
    template<ranges::forward_range R, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_unary_predicate
                 <std::projected<ranges::iterator_t<R>, Proj>> Pred>
        requires std::indirectly_copyable<ranges::iterator_t<R>, O>
    constexpr ranges::copy_if_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O d_first, Pred pred, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r),
                       ranges::next(ranges::begin(r), ranges::end(r)),
                       std::move(d_first), std::ref(pred), std::ref(proj));
    }
};

inline constexpr copy_if_fn copy_if;

Example

The following code uses ranges::copy to both copy the contents of one std::vector to another and to display the resulting std::vector.

#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

int main()
{
    std::vector<int> source(10);
    std::iota(source.begin(), source.end(), 0);
    std::vector<int> destination;
    std::ranges::copy(source.begin(), source.end(), std::back_inserter(destination));
    
// or, alternatively,
//  std::vector<int> destination(source.size());
//  std::ranges::copy(source.begin(), source.end(), destination.begin());
// either way is equivalent to
//  std::vector<int> destination = source;
    
    std::cout << "Destination contains: ";
    std::ranges::copy(destination, std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
    
    std::cout << "Odd numbers in destination are: ";
    std::ranges::copy_if(destination, std::ostream_iterator<int>(std::cout, " "),
                         [](int x) { return (x % 2) == 1; });
    std::cout << '\n';
}

Output:

Destination contains: 0 1 2 3 4 5 6 7 8 9
Odd numbers in destination are: 1 3 5 7 9

See also

copycopy_if
(C++11)
copies a range of elements to a new location
(function template)
ranges::copy_backward
(C++20)
copies a range of elements in backwards order
(algorithm function object)
ranges::reverse_copy
(C++20)
creates a copy of a range that is reversed
(algorithm function object)
ranges::copy_n
(C++20)
copies a number of elements to a new location
(algorithm function object)
ranges::fill
(C++20)
assigns a range of elements a certain value
(algorithm function object)
ranges::remove_copyranges::remove_copy_if
(C++20)(C++20)
copies a range of elements omitting those that satisfy specific criteria
(algorithm function object)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/ranges/copy

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API