Skip to main content

std::ranges::partition_copy() algorithm

// (1)
constexpr partition_copy_result<I, O1, O2>
partition_copy( I first, S last, O1 out_true, O2 out_false,
Pred pred, Proj proj = {} );

// (2)
constexpr partition_copy_result<ranges::borrowed_iterator_t<R>, O1, O2>
partition_copy( R&& r, O1 out_true, O2 out_false,
Pred pred, Proj proj = {} );

The type of arguments are generic and have the following constraints:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • O1, O2 - std::weakly_incrementable
  • R - std::ranges::forward_range
  • Pred:
    • (1) - std::indirect_unary_predicate<std::projected<I, Proj>>
    • (2) - std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>, Proj>>
  • Proj - (none)

The Proj template argument has the following default type std::identity for all overloads.

Additionally, each overload has the following constraints:

  • (1) - indirectly_copyable<I, O1> && indirectly_copyable<I, O2>
  • (2) - indirectly_copyable<ranges::iterator_t<R>, O1> && indirectly_copyable<ranges::iterator_t<R>, O2>

(The std:: namespace was omitted here for readability)

  • (1) Copies the elements from the input range [first; last) to two different output ranges depending on the value returned by the predicate pred.

    The elements that satisfy the predicate pred after projection by proj are copied to the range beginning at out_true.
    The rest of the elements are copied to the range beginning at out_false.

    Undefined Behaviour

    The behavior is undefined

    if the input range overlaps either of the output ranges.

  • (2) Same as (1), but uses r as the range, as if using ranges::begin(r) as first and ranges::end(r) as last.

The function-like entities described on this page are niebloids.

Parameters

first
last

The input range of elements to copy from.

r

The input range of elements to copy from.

out_true

The beginning of the output range for the elements that satisfy pred.

out_false

The beginning of the output range for the elements that don't satisfy pred.

pred

The predicate to apply to the projected elements.

proj

The projection to apply to the elements.

Return value

{
last,
o1,
o2
}

Where o1 and o2 are the ends of the output ranges respectively, after the copying is complete.

Complexity

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

Exceptions

(none)

Possible implementation

partition_copy(1) and partition_copy(2)
struct partition_copy_fn
{
template<std::input_iterator I, std::sentinel_for<I> S,
std::weakly_incrementable O1, std::weakly_incrementable O2,
class Proj = std::identity, std::indirect_unary_predicate<
std::projected<I, Proj>> Pred>
requires std::indirectly_copyable<I, O1> && std::indirectly_copyable<I, O2>
constexpr ranges::partition_copy_result<I, O1, O2>
operator()(I first, S last, O1 out_true, O2 out_false, Pred pred, Proj proj = {}) const
{
for (; first != last; ++first)
if (!!std::invoke(pred, std::invoke(proj, *first)))
*out_true = *first, ++out_true;
else
*out_false = *first, ++out_false;
return {std::move(first), std::move(out_true), std::move(out_false)};
}

template<ranges::input_range R,
std::weakly_incrementable O1, std::weakly_incrementable O2,
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<iterator_t<R>, Proj>> Pred>
requires std::indirectly_copyable<ranges::iterator_t<R>, O1> &&
std::indirectly_copyable<ranges::iterator_t<R>, O2>
constexpr ranges::partition_copy_result<ranges::borrowed_iterator_t<R>, O1, O2>
operator()(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(out_true),
std::move(out_false), std::move(pred), std::move(proj));
}
};

inline constexpr partition_copy_fn partition_copy {};

Examples

Main.cpp
#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
const auto in = {'N', '3', 'U', 'M', '1', 'B', '4', 'E', '1', '5', 'R', '9'};

std::vector<int> o1(size(in)), o2(size(in));

auto pred = [](char c) { return std::isalpha(c); };

auto ret = std::ranges::partition_copy(in, o1.begin(), o2.begin(), pred);

std::ostream_iterator<char> cout {std::cout, " "};
std::cout << "in = ";
std::ranges::copy(in, cout);
std::cout << "\no1 = ";
std::copy(o1.begin(), ret.out1, cout);
std::cout << "\no2 = ";
std::copy(o2.begin(), ret.out2, cout);
std::cout << '\n';
}
Possible Output
in = N 3 U M 1 B 4 E 1 5 R 9
o1 = N U M B E R
o2 = 3 1 4 1 5 9
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::ranges::partition_copy() algorithm

// (1)
constexpr partition_copy_result<I, O1, O2>
partition_copy( I first, S last, O1 out_true, O2 out_false,
Pred pred, Proj proj = {} );

// (2)
constexpr partition_copy_result<ranges::borrowed_iterator_t<R>, O1, O2>
partition_copy( R&& r, O1 out_true, O2 out_false,
Pred pred, Proj proj = {} );

The type of arguments are generic and have the following constraints:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • O1, O2 - std::weakly_incrementable
  • R - std::ranges::forward_range
  • Pred:
    • (1) - std::indirect_unary_predicate<std::projected<I, Proj>>
    • (2) - std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>, Proj>>
  • Proj - (none)

The Proj template argument has the following default type std::identity for all overloads.

Additionally, each overload has the following constraints:

  • (1) - indirectly_copyable<I, O1> && indirectly_copyable<I, O2>
  • (2) - indirectly_copyable<ranges::iterator_t<R>, O1> && indirectly_copyable<ranges::iterator_t<R>, O2>

(The std:: namespace was omitted here for readability)

  • (1) Copies the elements from the input range [first; last) to two different output ranges depending on the value returned by the predicate pred.

    The elements that satisfy the predicate pred after projection by proj are copied to the range beginning at out_true.
    The rest of the elements are copied to the range beginning at out_false.

    Undefined Behaviour

    The behavior is undefined

    if the input range overlaps either of the output ranges.

  • (2) Same as (1), but uses r as the range, as if using ranges::begin(r) as first and ranges::end(r) as last.

The function-like entities described on this page are niebloids.

Parameters

first
last

The input range of elements to copy from.

r

The input range of elements to copy from.

out_true

The beginning of the output range for the elements that satisfy pred.

out_false

The beginning of the output range for the elements that don't satisfy pred.

pred

The predicate to apply to the projected elements.

proj

The projection to apply to the elements.

Return value

{
last,
o1,
o2
}

Where o1 and o2 are the ends of the output ranges respectively, after the copying is complete.

Complexity

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

Exceptions

(none)

Possible implementation

partition_copy(1) and partition_copy(2)
struct partition_copy_fn
{
template<std::input_iterator I, std::sentinel_for<I> S,
std::weakly_incrementable O1, std::weakly_incrementable O2,
class Proj = std::identity, std::indirect_unary_predicate<
std::projected<I, Proj>> Pred>
requires std::indirectly_copyable<I, O1> && std::indirectly_copyable<I, O2>
constexpr ranges::partition_copy_result<I, O1, O2>
operator()(I first, S last, O1 out_true, O2 out_false, Pred pred, Proj proj = {}) const
{
for (; first != last; ++first)
if (!!std::invoke(pred, std::invoke(proj, *first)))
*out_true = *first, ++out_true;
else
*out_false = *first, ++out_false;
return {std::move(first), std::move(out_true), std::move(out_false)};
}

template<ranges::input_range R,
std::weakly_incrementable O1, std::weakly_incrementable O2,
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<iterator_t<R>, Proj>> Pred>
requires std::indirectly_copyable<ranges::iterator_t<R>, O1> &&
std::indirectly_copyable<ranges::iterator_t<R>, O2>
constexpr ranges::partition_copy_result<ranges::borrowed_iterator_t<R>, O1, O2>
operator()(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(out_true),
std::move(out_false), std::move(pred), std::move(proj));
}
};

inline constexpr partition_copy_fn partition_copy {};

Examples

Main.cpp
#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
const auto in = {'N', '3', 'U', 'M', '1', 'B', '4', 'E', '1', '5', 'R', '9'};

std::vector<int> o1(size(in)), o2(size(in));

auto pred = [](char c) { return std::isalpha(c); };

auto ret = std::ranges::partition_copy(in, o1.begin(), o2.begin(), pred);

std::ostream_iterator<char> cout {std::cout, " "};
std::cout << "in = ";
std::ranges::copy(in, cout);
std::cout << "\no1 = ";
std::copy(o1.begin(), ret.out1, cout);
std::cout << "\no2 = ";
std::copy(o2.begin(), ret.out2, cout);
std::cout << '\n';
}
Possible Output
in = N 3 U M 1 B 4 E 1 5 R 9
o1 = N U M B E R
o2 = 3 1 4 1 5 9
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.