Spec-Zone.ru › C++

std::contiguous_iterator

Определён в заголовочном файле <iterator>
template< class I >
    concept contiguous_iterator =
        std::random_access_iterator<I> &&
        std::derived_from</*ITER_CONCEPT*/<I>, std::contiguous_iterator_tag> &&
        std::is_lvalue_reference_v<std::iter_reference_t<I>> &&
        std::same_as<std::iter_value_t<I>,
                     std::remove_cvref_t<std::iter_reference_t<I>>> &&
        requires(const I& i) {
            { std::to_address(i) } ->
              std::same_as<std::add_pointer_t<std::iter_reference_t<I>>>;
        };
(начиная с C++20)

Концепт contiguous_iterator уточняет random_access_iterator, гарантируя, что обозначаемые элементы хранятся в памяти непрерывно.

Пусть итератор i имеет тип, моделирующий contiguous_iterator, сентинел — s, а неотрицательное целое число — n:

  • Для любого диапазона [i, s) стандартные библиотечные функции могут заменить его на [std::to_address(i), std::to_address(i + ranges::distance(i, s))).
  • Для любого диапазона i + [0, n) стандартные библиотечные функции могут заменить его на std::to_address(i) + [0, std::to_address(i + n)).

Это означает, что программа не может полагаться на побочные эффекты разыменования, инкремента или декремента непрерывного итератора i, поскольку стандартные библиотечные функции могут работать с указателями, полученными с помощью std::to_address(i), вместо непосредственной работы с i.

(начиная с C++26)

Определение концепта итератора

Определение этого концепта задаётся с помощью шаблона псевдонима, предназначенного только для описания, /*ITER_CONCEPT*/.

Чтобы определить /*ITER_CONCEPT*/<I>, обозначим через ITER_TRAITS<I> значение I, если специализация std::iterator_traits<I> создана из первичного шаблона, и std::iterator_traits<I> в противном случае:

  • Если ITER_TRAITS<I>::iterator_concept корректно и обозначает тип, /*ITER_CONCEPT*/<I> обозначает этот тип.
  • Иначе, если ITER_TRAITS<I>::iterator_category корректно и обозначает тип, /*ITER_CONCEPT*/<I> обозначает этот тип.
  • Иначе, если std::iterator_traits<I> создано из первичного шаблона, /*ITER_CONCEPT*/<I> обозначает std::random_access_iterator_tag.
    (То есть предполагается, что std::derived_from</*ITER_CONCEPT*/<I>, std::contiguous_iterator_tag> — это false.)
  • Иначе /*ITER_CONCEPT*/<I> не обозначает тип и приводит к сбою подстановки.

Семантические требования

Пусть a и b — разыменовываемые итераторы, а c — неразыменовываемый итератор типа I, такой что b достижим из a, а c достижим из b. Тип I моделирует contiguous_iterator только в том случае, если моделируются все включаемые им концепты и выполняются все следующие условия:

  • std::to_address(a) == std::addressof(*a).
  • std::to_address(b) == std::to_address(a) + std::iter_difference_t<I>(b - a).
  • std::to_address(c) == std::to_address(a) + std::iter_difference_t<I>(c - a).
  • std::to_address(I{}) корректно определено.
  • ranges::iter_move(a) имеет тот же тип, категорию значения и эффекты, что и std::move(*a).
  • Если ranges::iter_swap(a, b) корректно сформировано, оно имеет эффекты, эквивалентные ranges::swap(*a, *b).

Сохранение равенства

Выражения, объявленные в выражениях requires стандартных библиотечных концептов, должны сохранять равенство (если не указано иное).

Неявные варианты выражений

Выражение requires, в котором используется выражение, не изменяющее некоторый константный операнд-левостороннее значение, также требует наличия неявных вариантов выражений.

Примечания

Концепт contiguous_iterator моделируется всеми типами указателей на полные объектные типы.

Типы итераторов стандартной библиотеки, которые в C++17 должны удовлетворять требованиям LegacyContiguousIterator, в C++20 также должны моделировать contiguous_iterator.

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение согласно опубликованному стандарту Корректное поведение
LWG 3607 C++20 contiguous_iterator мог иметь пользовательские
поведения ranges::iter_move и ranges::iter_swap
запрещено
LWG 4170 C++20 пара инициализированных значением contiguous_iterator
могла не представлять пустой диапазон
гарантировано

См. также

random_access_iterator
(C++20)
задаёт, что bidirectional_iterator является итератором произвольного доступа, поддерживающим перемещение за постоянное время и индексирование
(концепт)

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

Spec-Zone.ru

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