std::ranges::replace_copy, std::ranges::replace_copy_if, std::ranges::replace_copy_result, std::ranges::replace_copy_if_result
Определено в заголовке <algorithm> | ||
|---|---|---|
| Подпись вызова | ||
template< std::input_iterator I, std::sentinel_for<I> S, class T1, class T2,
std::output_iterator<const T2&> O, class Proj = std::identity >
requires std::indirectly_copyable<I, O> &&
std::indirect_binary_predicate<ranges::equal_to,
std::projected<I, Proj>, const T1*>
constexpr replace_copy_result<I, O>
replace_copy( I first, S last, O result, const T1& old_value, const T2& new_value,
Proj proj = {} ); | (1) | (с C++20) |
template< ranges::input_range R, class T1, class T2,
std::output_iterator<const T2&> O, 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 T1*>
constexpr replace_copy_result<ranges::borrowed_iterator_t<R>, O>
replace_copy( R&& r, O result, const T1& old_value, const T2& new_value,
Proj proj = {} );
| (2) | (с C++20) |
template< std::input_iterator I, std::sentinel_for<I> S, class T,
std::output_iterator<const T&> O, class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
requires std::indirectly_copyable<I, O>
constexpr replace_copy_if_result<I, O>
replace_copy_if( I first, S last, O result, Pred pred, const T& new_value,
Proj proj = {} ); | (3) | (с C++20) |
template< ranges::input_range R, class T, std::output_iterator<const T&> 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 replace_copy_if_result<ranges::borrowed_iterator_t<R>, O>
replace_copy_if( R&& r, O result, Pred pred, const T& new_value,
Proj proj = {} );
| (4) | (с C++20) |
| Вспомогательные типы | ||
template< class I, class O > using replace_copy_result = ranges::in_out_result<I, O>; | (5) | (с C++20) |
template< class I, class O > using replace_copy_if_result = ranges::in_out_result<I, O>; | (6) | (с C++20) |
Копирует элементы из диапазона-источника [first, last) в диапазон-приемник, начинающийся с result, заменяя все элементы, удовлетворяющие определенным критериям, на new_value. Поведение не определено, если диапазоны-источник и-приемник перекрываются.
1) Заменяет все элементы, равные
old_value, используя std::invoke(proj, *(first + (i - result))) == old_value для сравнения.
3) Заменяет все элементы, для которых предикат
pred возвращает значение true, где выражение для вычисления предикатов - std::invoke(pred, std::invoke(proj, *(first + (i - result)))).
2,4) То же, что (1,3), но использует
r в качестве диапазона-источника, как если бы ranges::begin(r) использовалось как first, и ranges::end(r) как last. Функциональные сущности, описанные на этой странице, являются niebloids, т.е.:
- Явные списки шаблонов аргументов не могут быть указаны при вызове ни одного из них.
- Ни один из них не виден для поиска по зависимым от аргументов именам.
- Когда любой из них найден обычным поиском по незаданному имени как имя слева от оператора вызова функции, поиск по зависимым от аргументов именам заблокирован.
На практике они могут быть реализованы как объекты-функции или с использованием специальных расширений компилятора.
Параметры
| first, last | - | диапазон элементов для копирования |
| r | - | диапазон элементов для копирования |
| result | - | начало диапазона-приемника |
| old_value | - | значение элементов для замены |
| new_value | - | значение, используемое для замены |
| pred | - | предикат для применения к проецированным элементам |
| proj | - | проекция для применения к элементам. |
Возвращаемое значение
{last, result + N}, где
1,3)
N = ranges::distance(first, last);
2,4)
N = ranges::distance(r).Сложность
Точно N приложений соответствующего предиката comp и любой проекции proj.
Возможная реализация
| replace_copy (1-2) |
|---|
struct replace_copy_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class T1, class T2,
std::output_iterator<const T2&> O, class Proj = std::identity>
requires std::indirectly_copyable<I, O> &&
std::indirect_binary_predicate<ranges::equal_to,
std::projected<I, Proj>, const T1*>
constexpr ranges::replace_copy_result<I, O>
operator()(I first, S last, O result, const T1& old_value, const T2& new_value,
Proj proj = {}) const
{
for (; first != last; ++first, ++result)
*result = (std::invoke(proj, *first) == old_value) ? new_value : *first;
return {std::move(first), std::move(result)};
}
template<ranges::input_range R, class T1, class T2,
std::output_iterator<const T2&> O, 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 T1*>
constexpr ranges::replace_copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result, const T1& old_value, const T2& new_value,
Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result),
old_value, new_value, std::move(proj));
}
};
inline constexpr replace_copy_fn replace_copy {}; |
| replace_copy_if (3-4) |
struct replace_copy_if_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class T,
std::output_iterator<const T&> O,
class Proj = std::identity, std::indirect_unary_predicate<
std::projected<I, Proj>> Pred>
requires std::indirectly_copyable<I, O>
constexpr ranges::replace_copy_if_result<I, O>
operator()(I first, S last, O result, Pred pred, const T& new_value,
Proj proj = {}) const
{
for (; first != last; ++first, ++result)
*result = std::invoke(pred, std::invoke(proj, *first)) ? new_value : *first;
return {std::move(first), std::move(result)};
}
template<ranges::input_range R, class T, std::output_iterator<const T&> 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::replace_copy_if_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result, Pred pred, const T& new_value,
Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result),
std::move(pred), new_value, std::move(proj));
}
};
inline constexpr replace_copy_if_fn replace_copy_if {}; |
Пример
#include <algorithm>
#include <array>
#include <iostream>
#include <vector>
int main()
{
auto print = [](const auto rem, const auto& v)
{
for (std::cout << rem << ": "; const auto& e : v)
std::cout << e << ' ';
std::cout << '\n';
};
std::vector<int> o;
std::array p {1, 6, 1, 6, 1, 6};
o.resize(p.size());
print("p", p);
std::ranges::replace_copy(p, o.begin(), 6, 9);
print("o", o);
std::array q {1, 2, 3, 6, 7, 8, 4, 5};
o.resize(q.size());
print("q", q);
std::ranges::replace_copy_if(q, o.begin(), [](int x) { return 5 < x; }, 5);
print("o", o);
}Вывод:
p: 1 6 1 6 1 6 o: 1 9 1 9 1 9 q: 1 2 3 6 7 8 4 5 o: 1 2 3 5 5 5 4 5
См. также
|
(C++20)(C++20) | заменяет все значения, удовлетворяющие определенным критериям, другим значением (niebloid) |
| копирует диапазон, заменяя элементы, удовлетворяющие определенным критериям, другим значением (функция-шаблон) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/ranges/replace_copy