Namespaces
Variants
Views
Actions

std::ranges::remove_copy, std::ranges::remove_copy_if, std::ranges::remove_copy_result, std::ranges::remove_copy_if_result

From cppreference.com
< cpp‎ | algorithm‎ | ranges
Revision as of 20:09, 4 December 2020 by Space Mission (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
 
 
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
(C++11)                (C++11)(C++11)

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
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
C library
Numeric operations
Operations on uninitialized memory
 
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
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
Fold operations
Numeric operations
(C++23)            
Operations on uninitialized storage
Return types
 
Defined in header <algorithm>
Call signature
template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,

         class T, class Proj = std::identity>
  requires std::indirectly_copyable<I, O> &&
      std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>, const T*>
    constexpr ranges::remove_copy_result<I, O>

      ranges::remove_copy( I first, S last, O result, const T& value, Proj proj = {} );
(1) (since C++20)
template<ranges::input_range R, std::weakly_incrementable O, class T,

         class Proj = std::identity>
  requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
           std::indirect_binary_predicate<ranges::equal_to,
             std::projected<ranges::iterator_t<R>, Proj>, const T*>
    constexpr ranges::remove_copy_result<ranges::borrowed_iterator_t<R>, O>

      ranges::remove_copy( R&& r, O result, const T& value, Proj proj = {} );
(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 ranges::remove_copy_if_result<I, O>

      ranges::remove_copy_if( I first, S last, O result, 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 ranges::remove_copy_if_result<ranges::borrowed_iterator_t<R>, O>

      ranges::remove_copy_if( R&& r, O result, Pred pred, Proj proj = {} );
(4) (since C++20)
Helper types
template<class I, class O>
  using remove_copy_result = ranges::in_out_result<I, O>;
(5) (since C++20)
template<class I, class O>
  using remove_copy_if_result = ranges::in_out_result<I, O>;
(6) (since C++20)

Copies elements from the source range [first, last), to the destination range beginning at result, omitting the elements which (after being projected by proj) satisfy specific criteria. Precondition: the source and destination ranges do not overlap.

1) Ignores all elements that are equal to value.
3) Ignores all elements for which predicate pred returns true.
2,4) Same as (1,3), but uses r as the soruce range, as if using ranges::begin(r) as first, and ranges::end(r) as last.

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

Contents

Parameters

first, last - the source range of elements
r - the source range of elements
result - the beginning of the destination range
value - the value of the elements not to copy
comp - the binary predicate to compare the projected elements
proj - the projection to apply to the elements.

Return value

Returns an object {last, result + N}, where N is the number of elements copied.

Complexity

Exactly ranges::distance(first, last) applications of the corresponding predicate comp and any projection proj.

Notes

The algorithm is stable, i.e. preserves the relative order of the copied elements.

Possible implementation

First version
struct remove_copy_fn {
  template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
           class T, class Proj = std::identity>
    requires std::indirectly_copyable<I, O> &&
        std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>, const T*>
      constexpr ranges::remove_copy_result<I, O>
        operator()( I first, S last, O result, const T& value, Proj proj = {} ) const {
            for (; !(first == last); ++first) {
                if (value != std::invoke(proj, *first)) {
                    *result = *first;
                    ++result;
                }
            }
            return {std::move(first), std::move(result)};
        }
 
  template<ranges::input_range R, std::weakly_incrementable O, class T,
           class Proj = std::identity>
    requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
             std::indirect_binary_predicate<ranges::equal_to,
               std::projected<ranges::iterator_t<R>, Proj>, const T*>
      constexpr ranges::remove_copy_result<ranges::borrowed_iterator_t<R>, O>
        operator()( R&& r, O result, const T& value, Proj proj = {} ) const {
           return (*this)(ranges::begin(r), ranges::end(r), std::move(result),
                          value, std::move(proj));
        }
};
inline constexpr remove_copy_fn remove_copy{};
Second version
struct remove_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::remove_copy_if_result<I, O>
        operator()( I first, S last, O result, Pred pred, Proj proj = {} ) const {
            for (; first != last; ++first) {
                if (false == std::invoke(pred, std::invoke(proj, *first))) {
                    *result = *first;
                    ++result;
                }
            }
            return {std::move(first), std::move(result)};
        }
 
  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::remove_copy_if_result<ranges::borrowed_iterator_t<R>, O>
        operator()( R&& r, O result, Pred pred, Proj proj = {} ) const {
          return (*this)(ranges::begin(r), ranges::end(r), std::move(result),
                         std::move(pred), std::move(proj));
        }
};
inline constexpr remove_copy_if_fn remove_copy_if_{};

Example

#include <algorithm>
#include <array>
#include <complex>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string_view>
#include <vector>
 
void print(const auto rem, const auto& v) {
    std::cout << rem << ' ';
    for (const auto& e : v) { std::cout << e << ' '; };
    std::cout << '\n';
}
 
int main()
{
    // Filter out the hash symbol from the given string.
    const std::string_view str{ "#Small #Buffer #Optimization" };
    std::cout << "before: " << std::quoted(str) << "\n";
 
    std::cout << "after:  \"";
    std::ranges::remove_copy(str.begin(), str.end(),
                             std::ostream_iterator<char>(std::cout), '#');
    std::cout << "\"\n";
 
 
    // Copy only the complex numbers with positive imaginary part.
    using Ci = std::complex<int>;
    constexpr std::array<Ci, 5> source{
        Ci{1,0}, Ci{0,1}, Ci{2,-1}, Ci{3,2}, Ci{4,-3}
    };
    std::vector<std::complex<int>> target;
 
    std::ranges::remove_copy_if(source,
        std::back_inserter(target),
        [](int imag){ return imag <= 0; },
        [](Ci z){ return z.imag(); }
    );
 
    print("source:", source);
    print("target:", target);
}

Output:

before: "#Small #Buffer #Optimization"
after:  "Small Buffer Optimization"
source: (1,0) (0,1) (2,-1) (3,2) (4,-3)
target: (0,1) (3,2)

See also

removes elements satisfying specific criteria
(algorithm function object)[edit]
copies a range of elements to a new location
(algorithm function object)[edit]
copies a number of elements to a new location
(algorithm function object)[edit]
copies a range of elements in backwards order
(algorithm function object)[edit]
copies a range, replacing elements satisfying specific criteria with another value
(algorithm function object)[edit]
creates a copy of a range that is reversed
(algorithm function object)[edit]
copies and rotate a range of elements
(algorithm function object)[edit]
creates a copy of some range of elements that contains no consecutive duplicates
(algorithm function object)[edit]
copies a range of elements omitting those that satisfy specific criteria
(function template) [edit]