Spec-Zone.ru › C++

std::ranges::copy_n, std::ranges::copy_n_result

Определён в заголовочном файле <algorithm>
Сигнатура вызова
template< std::input_iterator I, std::weakly_incrementable O >
    requires std::indirectly_copyable<I, O>
constexpr copy_n_result<I, O>
    copy_n( I first, std::iter_difference_t<I> count, O d_first );
(1) (начиная с C++20)
template< /*execution-policy*/ Ep, std::random_access_iterator I,
          std::random_access_iterator O, std::sized_sentinel_for<O> OutS >
    requires std::indirectly_copyable<I, O>
copy_n_result<I, O>
    copy_n( Ep&& policy, I first, iter_difference_t<I> count,
            O d_first, OutS d_last );
(2) (начиная с C++26)
Вспомогательный тип
template< class I, class O >
using copy_n_result = ranges::in_out_result<I, O>;
(3) (начиная с C++20)

Определение /*execution-policy*/ см. на этой странице.

Если count положительно, элементы исходного диапазона [first, ranges::next(first, count)) копируются в целевой диапазон. В противном случае функция ничего не делает.

1) Целевой диапазон — [d_first, ranges::next(d_first, count)).
2) Порядок копирования определяется policy, а целевой диапазон — [d_first, d_last). Если целевой диапазон закончится раньше, чем будет достигнут конец исходного диапазона, оставшиеся элементы исходного диапазона не будут скопированы.

Описанные на этой странице функциональные объекты — это функциональные объекты алгоритмов (неофициально называемые niebloids), то есть:

  • При вызове любого из них нельзя указать явный список аргументов шаблона.
  • Ни один из них не виден для поиска, зависящего от аргументов.
  • Если любой из них найден при помощи обычного неквалифицированного поиска как имя слева от оператора вызова функции, поиск, зависящий от аргументов, блокируется.

Параметры

first - начало исходного диапазона
count - количество копируемых элементов
d_first - начало целевого диапазона
policy - используемая политика выполнения

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

Объект ranges::copy_n_result, в котором:

  • Поле данных in содержит итератор, указывающий на элемент, следующий за последним скопированным элементом исходного диапазона, или итератор на начало исходного диапазона, если ни один элемент не скопирован.
  • Поле данных out содержит итератор, указывающий на элемент, следующий за последним элементом целевого диапазона, в который было выполнено копирующее присваивание, или итератор на начало целевого диапазона, если ни один элемент не скопирован.

Сложность

Обозначим

  • \(\scriptsize N_1\)N1 как \(\scriptsize \max(\mathtt{count},0)\)max(count,0), и
  • \(\scriptsize N_2\)N2 как ranges::distance(d_first, d_last):
1) Ровно \(\scriptsize N_1\)N1 операций присваивания.
2) Ровно \(\scriptsize \min(N_1,N_2)\)min(N1,N2) операций присваивания.

Исключения

2) В процессе выполнения:
  • Если требуемые для распараллеливания временные ресурсы памяти недоступны, выбрасывается std::bad_alloc.
  • Если при обращении к объектам через аргумент алгоритма выбрасывается неперехваченное исключение, поведение определяется политикой выполнения (для стандартных политик вызывается std::terminate).

Примечания

На практике реализации ranges::copy_n могут избегать множественных операций присваивания и использовать функции массового копирования, такие как std::memmove, если тип значения является TriviallyCopyable, а типы итераторов удовлетворяют требованиям contiguous_iterator. Также такое ускорение копирования может быть добавлено на этапе оптимизации компилятора.

При копировании перекрывающихся диапазонов ranges::copy_n подходит для копирования влево (начало целевого диапазона находится вне исходного диапазона), а ranges::copy_backward — для копирования вправо (конец целевого диапазона находится вне исходного диапазона).

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

struct copy_n_fn
{
    template<std::input_iterator I, std::weakly_incrementable O>
        requires std::indirectly_copyable<I, O>
    constexpr ranges::copy_n_result<I, O>
        operator()(I first, std::iter_difference_t<I> n, O d_first) const
    {
        for (; n-- > 0; (void)++first, (void)++d_first)
            *d_first = *first;
        
        return {std::move(first), std::move(d_first)};
    }
};

inline constexpr copy_n_fn copy_n{};

Пример

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <string_view>

int main()
{
    const std::string_view in{"ABCDEFGH"};
    std::string out;
    
    std::ranges::copy_n(in.begin(), 4, std::back_inserter(out));
    std::cout << std::quoted(out) << '\n';
    
    out = "abcdefgh";
    const auto res{std::ranges::copy_n(in.begin(), 5, out.begin())};
    const auto i{std::distance(std::begin(in), res.in)};
    const auto j{std::distance(std::begin(out), res.out)};
    std::cout << "in[" << i << "] = '" << in[i] << "'\n"
              << "out[" << j << "] = '" << out[j] << "'\n";
}

Вывод:

"ABCD"
in[5] = 'F'
out[5] = 'f'

См. также

copy_n
(C++11)
копирует заданное количество элементов в новое место
(функция-шаблон)
ranges::copyranges::copy_if
(C++20)(C++20)
копирует диапазон элементов в новое место
(функциональный объект алгоритма)
ranges::copy_backward
(C++20)
копирует диапазон элементов в обратном порядке
(функциональный объект алгоритма)
ranges::remove_copyranges::remove_copy_if
(C++20)(C++20)
копирует диапазон элементов, исключая те, которые удовлетворяют заданным условиям
(функциональный объект алгоритма)
ranges::replace_copyranges::replace_copy_if
(C++20)(C++20)
копирует диапазон, заменяя элементы, удовлетворяющие заданным условиям, другим значением
(функциональный объект алгоритма)
ranges::reverse_copy
(C++20)
создаёт копию диапазона в обратном порядке
(функциональный объект алгоритма)
ranges::rotate_copy
(C++20)
копирует и циклически сдвигает диапазон элементов
(функциональный объект алгоритма)
ranges::unique_copy
(C++20)
создаёт копию диапазона элементов без последовательных дубликатов
(функциональный объект алгоритма)
ranges::move
(C++20)
перемещает диапазон элементов в новое место
(функциональный объект алгоритма)
ranges::move_backward
(C++20)
перемещает диапазон элементов в новое место в обратном порядке
(функциональный объект алгоритма)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/ranges/copy_n

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API