Namespaces
Variants

std::experimental::ranges:: copy, std::experimental::ranges:: copy_if

From ru.cppreference.net
**Примечание:** В данном фрагменте кода все текстовые элементы уже являются техническими терминами C++ (имена шаблонов, концепций, функций и т.д.), которые согласно требованиям не подлежат переводу. HTML-разметка и содержимое тегов `` также сохранены в оригинальном виде. **Примечание:** Весь текст в данном фрагменте содержит исключительно C++ код и специфические термины программирования, которые не подлежат переводу согласно предоставленным инструкциям. HTML-разметка, теги ``, `
`, `` отсутствуют, но все C++ конструкции (ключевые слова, имена функций, концепты, параметры шаблонов) сохранены в оригинальном виде.
Определено в заголовочном файле <experimental/ranges/algorithm>
template < InputIterator I, Sentinel < I > S, WeaklyIncrementable O >

requires IndirectlyCopyable < I, O >
ranges:: tagged_pair < tag:: in ( I ) , tag:: out ( O ) >

copy ( I first, S last, O result ) ;
(1) (ranges TS)
template < InputRange R, WeaklyIncrementable O >

requires IndirectlyCopyable < ranges:: iterator_t < R > , O >
ranges:: tagged_pair < tag:: in ( ranges:: safe_iterator_t < R > ) , tag:: out ( O ) >

copy ( R && r, O result ) ;
(2) (ranges TS)
template < InputIterator I, Sentinel < I > S, WeaklyIncrementable O,

class Proj = ranges:: identity ,
IndirectUnaryPredicate < projected < I, Proj >> Pred >
requires IndirectlyCopyable < I, O >
ranges:: tagged_pair < tag:: in ( I ) , tag:: out ( O ) >

copy_if ( I first, S last, O result, Pred pred, Proj proj = Proj { } ) ;
(3) (ranges TS)
template < InputRange R, WeaklyIncrementable O,

class Proj = ranges:: identity ,
IndirectUnaryPredicate < projected < ranges:: iterator_t < R > , Proj >> Pred >
requires IndirectlyCopyable < iterator_t < R > , O >
ranges:: tagged_pair < tag:: in ( ranges:: safe_iterator_t < R > ) , tag:: out ( O ) >

copy_if ( R && r, O result, Pred pred, Proj proj = Proj { } ) ;
(4) (ranges TS)

Копирует элементы из исходного диапазона ( [ first , last ) или r ) в диапазон назначения, начиная с result , начиная с первого элемента исходного диапазона и продвигаясь к последнему.

1) Копирует все элементы в диапазоне [ first , last ) . Для каждого неотрицательного целого числа n < (last - first) , выполняет * ( result + n ) = * ( first + n ) . Поведение не определено, если result находится в диапазоне [ first , last ) . В этом случае вместо этого может быть использована функция ranges::copy_backward .
2) То же, что и (1) , но использует r в качестве исходного диапазона, как если бы было выполнено ranges:: copy ( ranges:: begin ( r ) , ranges:: end ( r ) , result ) ; за исключением того, что result может не быть скопирован.
3) Копирует только те элементы, для которых предикат pred возвращает true при применении к значению элемента, спроецированному проекцией proj . Порядок копируемых элементов сохраняется. Поведение не определено, если исходный и целевой диапазоны перекрываются.
4) То же, что и (3) , но использует r в качестве исходного диапазона, как если бы было выполнено ranges:: copy_if ( ranges:: begin ( r ) , ranges:: end ( r ) , result, pred, proj ) ; за исключением того, что result , pred и proj могут не копироваться.

Несмотря на приведённые выше объявления, фактическое количество и порядок параметров шаблона для объявлений алгоритмов не определено. Таким образом, если при вызове алгоритма используются явные аргументы шаблона, программа, вероятно, является непереносимой.

Содержание

Параметры

first, last - диапазон элементов для копирования
r - диапазон элементов для копирования
result - начало целевого диапазона
pred - предикат для применения к проецируемым элементам
proj - проекция для применения к элементам

Возвращаемое значение

Объект tagged_pair содержащий следующие два члена:

  • Первый элемент, с тегом tag::in , является конечным итератором исходного диапазона (то есть итератором типа I , который сравнивается с сентинелом last ).
  • Второй элемент, с тегом tag::out , является конечным итератором результирующего диапазона.

Сложность

1) Ровно ranges:: distance ( first, last ) присваиваний.
2) Ровно ranges:: distance ( r ) присваиваний.
3) Ровно ranges:: distance ( first, last ) применений соответствующей проекции и предиката.
4) Ровно ranges:: distance ( r ) применений соответствующей проекции и предиката.

Возможные реализации

Первая версия
template<InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
    requires IndirectlyCopyable<I, O>()
ranges::tagged_pair<tag::in(I), tag::out(O)>
    copy(I first, S last, O result)
{
    for (; first != last; ++first, (void)++result)
        *result = *first;
    return {first, result};
}
Вторая версия
template<InputRange R, WeaklyIncrementable O>
    requires IndirectlyCopyable<ranges::iterator_t<R>, O>()
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>
    copy(R&& r, O result)
{
   return ranges::copy(ranges::begin(r), ranges::end(r), result);
}
Третья версия
template<InputIterator I, Sentinel<I> S, WeaklyIncrementable O,
         class Proj = ranges::identity,
         IndirectUnaryPredicate<projected<I, Proj>> Pred>
    requires IndirectlyCopyable<I, O>()
ranges::tagged_pair<tag::in(I), tag::out(O)>
    copy_if(I first, S last, O result, Pred pred, Proj proj = Proj{})
{
    for (; first != last; ++first)
        if (ranges::invoke(pred, ranges::invoke(proj, *first)))
        {
            *result = *first;
            ++result;
        }
    return {first, result};
}
Четвертая версия
template<InputRange R, WeaklyIncrementable O,
         class Proj = ranges::identity,
         IndirectUnaryPredicate<projected<ranges::iterator_t<R>, Proj>> Pred>
    requires IndirectlyCopyable<ranges::iterator_t<R>, O>()
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>
    copy_if(R&& r, O result, Pred pred, Proj proj = Proj{})
{
    return ranges::copy_if(ranges::begin(r), ranges::end(r), result, pred, proj);
}

Пример

Следующий код использует copy для копирования содержимого одного вектора в другой и для отображения результирующего вектора:

#include <experimental/ranges/algorithm>
#include <experimental/ranges/iterator>
#include <iostream>
#include <numeric>
#include <vector>
int main()
{
    // see https://ru.cppreference.net/w/cpp/language/namespace_alias
    namespace ranges = std::experimental::ranges;
    std::vector<int> from_vector(10);
    std::iota(from_vector.begin(), from_vector.end(), 0);
    std::vector<int> to_vector;
    ranges::copy_if(from_vector.begin(), from_vector.end(),
                    ranges::back_inserter(to_vector),
                    [](const auto i)
                    {
                       return i % 3;
                    });
// or, alternatively,
//  std::vector<int> to_vector(from_vector.size());
//  std::copy(from_vector, to_vector.begin());
    std::cout << "to_vector contains: ";
    ranges::copy(to_vector, ranges::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
}

Вывод:

to_vector contains: 1 2 4 5 7 8

Смотрите также

копирует диапазон элементов в новое место
(шаблон функции & функциональный объект алгоритма)
копирует диапазон элементов в обратном порядке
(шаблон функции)
создаёт копию диапазона в обратном порядке
(шаблон функции)
копирует указанное количество элементов в новое место
(шаблон функции)
присваивает диапазону элементов определённое значение
(шаблон функции)
копирует диапазон элементов, пропуская те, которые удовлетворяют определённым критериям
(шаблон функции)