Skip to main content

std::ranges::replace() algorithm

// (1)
constexpr I
replace( I first, S last, const T1& old_value, const T2& new_value,
Proj proj = {} );

// (2)
constexpr ranges::borrowed_iterator_t<R>
replace( R&& r, const T1& old_value, const T2& new_value, Proj proj = {} );

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

  • I - std::permutable
  • S - std::sentinel_for<I>
  • R - std::ranges::input_range
  • T1 - (none)
  • T2 - (none)
  • Proj - (none)

The Proj template argument has a default type of std::identity for all overloads.

Additionally, each overload has the following constraints:

  • (1):
    indirectly_writable<I, const T2&>
    && indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
  • (2):
    indirectly_writable<ranges::iterator_t<R>, const T2&>
    && indirect_binary_predicate<ranges::equal_to, projected<ranges::iterator_t<R>, Proj>, const T1*>

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

  • (1) Replaces all elements that are equal to old_value with new_value, using std::invoke(proj, *i) == old_value to compare.

  • (2) Same as (1), but uses r as the source 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 range of elements to process.

r

The range of elements to process.

old_value

The value to search for and replace.

new_value

The value to use as a replacement.

proj

Projection to apply to the elements.

Return value

An iterator equal to last.

Complexity

Exactly ranges::distance(first, last) applications of the projection proj.

Exceptions

(none)

Possible implementation

replace(1)
struct replace_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class T1, class T2,
class Proj = std::identity>
requires std::indirectly_writable<I, const T2&> && std::indirect_binary_predicate<
ranges::equal_to, std::projected<I, Proj>, const T1*>
constexpr I
operator()(I first, S last, const T1& old_value, const T2& new_value,
Proj proj = {}) const
{
for (; first != last; ++first)
if (old_value == std::invoke(proj, *first))
*first = new_value;
return first;
}

template<ranges::input_range R, class T1, class T2, class Proj = std::identity>
requires std::indirectly_writable<ranges::iterator_t<R>, const T2&> &&
std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), old_value,
new_value, std::move(proj));
}
};

inline constexpr replace_fn replace {};

Notes

Because the algorithm takes old_value and new_value by reference, it may have unexpected behavior if either is a reference to an element of the range [first; last).

Examples

Main.cpp

#include <algorithm>
#include <array>
#include <iostream>

int main()
{
auto print = [](const auto& v)
{
for (const auto& e : v)
std::cout << e << ' ';
std::cout << '\n';
};

std::array p {1, 6, 1, 6, 1, 6};
print(p);
std::ranges::replace(p, 6, 9);
print(p);

std::array q {1, 2, 3, 6, 7, 8, 4, 5};
print(q);
std::ranges::replace_if(q, [](int x) { return 5 < x; }, 5);
print(q);
}
Output
1 6 1 6 1 6
1 9 1 9 1 9
1 2 3 6 7 8 4 5
1 2 3 5 5 5 4 5
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::replace() algorithm

// (1)
constexpr I
replace( I first, S last, const T1& old_value, const T2& new_value,
Proj proj = {} );

// (2)
constexpr ranges::borrowed_iterator_t<R>
replace( R&& r, const T1& old_value, const T2& new_value, Proj proj = {} );

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

  • I - std::permutable
  • S - std::sentinel_for<I>
  • R - std::ranges::input_range
  • T1 - (none)
  • T2 - (none)
  • Proj - (none)

The Proj template argument has a default type of std::identity for all overloads.

Additionally, each overload has the following constraints:

  • (1):
    indirectly_writable<I, const T2&>
    && indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
  • (2):
    indirectly_writable<ranges::iterator_t<R>, const T2&>
    && indirect_binary_predicate<ranges::equal_to, projected<ranges::iterator_t<R>, Proj>, const T1*>

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

  • (1) Replaces all elements that are equal to old_value with new_value, using std::invoke(proj, *i) == old_value to compare.

  • (2) Same as (1), but uses r as the source 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 range of elements to process.

r

The range of elements to process.

old_value

The value to search for and replace.

new_value

The value to use as a replacement.

proj

Projection to apply to the elements.

Return value

An iterator equal to last.

Complexity

Exactly ranges::distance(first, last) applications of the projection proj.

Exceptions

(none)

Possible implementation

replace(1)
struct replace_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class T1, class T2,
class Proj = std::identity>
requires std::indirectly_writable<I, const T2&> && std::indirect_binary_predicate<
ranges::equal_to, std::projected<I, Proj>, const T1*>
constexpr I
operator()(I first, S last, const T1& old_value, const T2& new_value,
Proj proj = {}) const
{
for (; first != last; ++first)
if (old_value == std::invoke(proj, *first))
*first = new_value;
return first;
}

template<ranges::input_range R, class T1, class T2, class Proj = std::identity>
requires std::indirectly_writable<ranges::iterator_t<R>, const T2&> &&
std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), old_value,
new_value, std::move(proj));
}
};

inline constexpr replace_fn replace {};

Notes

Because the algorithm takes old_value and new_value by reference, it may have unexpected behavior if either is a reference to an element of the range [first; last).

Examples

Main.cpp

#include <algorithm>
#include <array>
#include <iostream>

int main()
{
auto print = [](const auto& v)
{
for (const auto& e : v)
std::cout << e << ' ';
std::cout << '\n';
};

std::array p {1, 6, 1, 6, 1, 6};
print(p);
std::ranges::replace(p, 6, 9);
print(p);

std::array q {1, 2, 3, 6, 7, 8, 4, 5};
print(q);
std::ranges::replace_if(q, [](int x) { return 5 < x; }, 5);
print(q);
}
Output
1 6 1 6 1 6
1 9 1 9 1 9
1 2 3 6 7 8 4 5
1 2 3 5 5 5 4 5
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.