Spec-Zone.ru › C++

Библиотека диапазонов (C++20)

Библиотека диапазонов является расширением и обобщением библиотек алгоритмов и итераторов, делающих их более мощными благодаря возможности композиции и снижению вероятности ошибок.

Библиотека создает и манипулирует представлениями диапазонов, легкими объектами, которые косвенно представляют итерируемые последовательности (диапазоны). Диапазоны представляют собой абстракцию над

  • [begin, end) – парами итераторов, например, диапазоны, созданные неявным преобразованием из контейнеров. Все алгоритмы, принимающие пары итераторов, теперь имеют перегрузки, принимающие диапазоны (например, ranges::sort)
  • begin + [​0​, size) – последовательности со счётчиком, например, диапазон, возвращаемый views::counted
  • [begin, предикатом) – последовательности с условной конечностью, например, диапазон, возвращаемый views::take_while
  • [begin, ..) – неограниченные последовательности, например, диапазон, возвращаемый views::iota

Библиотека диапазонов включает алгоритмы для диапазонов, которые применяются к диапазонам немедленно, и адаптеры диапазонов, которые применяются к представлениям лениво. Адаптеры могут быть объединены в цепочки, так что их действия выполняются при итерировании представления.

Определено в заголовке <ranges>
namespace std {
    namespace views = ranges::views;
}
(с C++20)

Псевдоним пространства имён std::views предоставляется в качестве сокращения для std::ranges::views.

Определено в пространстве имён std::ranges
Доступ к диапазону
Определено в заголовочном файле <ranges>
Определено в заголовочном файле <iterator>
ranges::begin
(C++20)
возвращает итератор начала диапазона
(объект точки кастомизации)
ranges::end
(C++20)
возвращает страж, обозначающий конец диапазона
(объект точки кастомизации)
ranges::cbegin
(C++20)
возвращает итератор начала только для чтения диапазона
(объект точки кастомизации)
ranges::cend
(C++20)
возвращает страж, обозначающий конец только для чтения диапазона
(объект точки кастомизации)
ranges::rbegin
(C++20)
возвращает обратный итератор диапазона
(объект точки кастомизации)
ranges::rend
(C++20)
возвращает обратный итератор конца диапазона
(объект точки кастомизации)
ranges::crbegin
(C++20)
возвращает обратный итератор только для чтения диапазона
(объект точки кастомизации)
ranges::crend
(C++20)
возвращает обратный итератор конца только для чтения диапазона
(объект точки кастомизации)
ranges::size
(C++20)
возвращает целое число, равное размеру диапазона
(объект точки кастомизации)
ranges::ssize
(C++20)
возвращает целое число со знаком, равное размеру диапазона
(объект точки кастомизации)
ranges::empty
(C++20)
проверяет, пуст ли диапазон
(объект точки кастомизации)
ranges::data
(C++20)
получает указатель на начало непрерывного диапазона
(объект точки кастомизации)
ranges::cdata
(C++20)
получает указатель на начало непрерывного диапазона только для чтения
(объект точки кастомизации)
Примитивы диапазонов
Определено в заголовочном файле <ranges>
ranges::iterator_tranges::const_iterator_tranges::sentinel_tranges::const_sentinel_tranges::range_difference_tranges::range_size_tranges::range_value_tranges::range_reference_tranges::range_const_reference_tranges::range_rvalue_reference_tranges::range_common_reference_t
(C++20)(C++23)(C++20)(C++23)(C++20)(C++20)(C++20)(C++20)(C++23)(C++20)(C++20)
получает связанные типы диапазона
(шаблон псевдонима)
Обработка висячих итераторов
Определено в заголовочном файле <ranges>
ranges::dangling
(C++20)
тип-заполнитель, указывающий, что итератор или subrange не должны возвращаться, поскольку он будет висячим
(класс)
ranges::borrowed_iterator_tranges::borrowed_subrange_t
(C++20)
получает тип итератора или тип subrange borrowed_range
(шаблон псевдонима)
Концепции диапазонов
Определено в заголовочном файле <ranges>
ranges::range
(C++20)
определяет, что тип является диапазоном, то есть он предоставляет итератор begin и страж end
(концепция)
ranges::borrowed_range
(C++20)
определяет, что тип является range, и итераторы, полученные от выражения, могут быть безопасно возвращены без опасности возникновения висячих
(концепция)
ranges::sized_range
(C++20)
определяет, что диапазон знает свой размер за постоянное время
(концепция)
ranges::view
(C++20)
определяет, что диапазон является представлением, то есть имеет время копирования/перемещения/присваивания за константу
(концепция)
ranges::input_range
(C++20)
определяет диапазон, тип итератора которого удовлетворяет input_iterator
(концепция)
ranges::output_range
(C++20)
определяет диапазон, тип итератора которого удовлетворяет output_iterator
(концепция)
ranges::forward_range
(C++20)
определяет диапазон, тип итератора которого удовлетворяет forward_iterator
(концепция)
END_OF_DOCUMENT_MARKER
ranges::bidirectional_range
(C++20)
определяет диапазон, тип итератора которого удовлетворяет bidirectional_iterator
(концепция)
ranges::random_access_range
(C++20)
определяет диапазон, тип итератора которого удовлетворяет random_access_iterator
(концепция)
ranges::contiguous_range
(C++20)
определяет диапазон, тип итератора которого удовлетворяет contiguous_iterator
(концепция)
ranges::common_range
(C++20)
определяет, что диапазон имеет идентичные типы итератора и конечной точки
(концепция)
ranges::viewable_range
(C++20)
определяет требования к range для безопасного преобразования в view
(концепция)
ranges::constant_range
(C++23)
определяет, что диапазон имеет только элементы для чтения
(концепция)
Преобразования диапазонов
Определено в заголовке <ranges>
ranges::to
(C++23)
создает новый объект без представления из входного диапазона
(шаблон функции)
Представления
Определено в заголовке <ranges>
ranges::view_interface
(C++20)
вспомогательный шаблон класса для определения view, используя шаблон с повторяющимся шаблоном
(шаблон класса)
ranges::subrange
(C++20)
объединяет пару итератор-конечная точка в view
(шаблон класса)

Фабрики диапазонов

Определено в заголовке <ranges>
Определено в пространстве имен std::ranges
ranges::empty_viewviews::empty
(C++20)
пустое view без элементов
(шаблон класса) (шаблон переменной)
ranges::single_viewviews::single
(C++20)
view, содержащее один элемент заданного значения
(шаблон класса) (объект точки кастомизации)
ranges::iota_viewviews::iota
(C++20)
view, состоящее из последовательности, генерируемой многократным инкрементированием начального значения
(шаблон класса) (объект точки кастомизации)
ranges::basic_istream_viewviews::istream
(C++20)
view, состоящее из элементов, получаемых последовательным применением operator>> к связанному потоку ввода
(шаблон класса) (объект точки кастомизации)
ranges::repeat_viewviews::repeat
(C++23)
view, состоящее из генерируемой последовательности, повторно производящей одно и то же значение
(шаблон класса) (объект точки кастомизации)

Адаптеры диапазонов

Определено в заголовке <ranges>
Определено в пространстве имен std::ranges
ranges::range_adaptor_closure
(C++23)
шаблон базового класса-помощника для определения объекта адаптера диапазона
(шаблон класса)
views::all_tviews::all
(C++20)
view, содержащий все элементы range
(шаблон псевдонима) (объект адаптера диапазона)
ranges::ref_view
(C++20)
view элементов другого range
(шаблон класса)
ranges::owning_view
(C++20)
view с уникальной собственностью на некоторый range
(шаблон класса)
ranges::filter_viewviews::filter
(C++20)
view, состоящий из элементов range, удовлетворяющих предикату
(шаблон класса) (объект адаптера диапазона)
ranges::transform_viewviews::transform
(C++20)
view последовательности, применяющей функцию преобразования к каждому элементу
(шаблон класса) (объект адаптера диапазона)
ranges::take_viewviews::take
(C++20)
view, состоящий из первых N элементов другого view
(шаблон класса) (объект адаптера диапазона)
ranges::take_while_viewviews::take_while
(C++20)
view, состоящий из начальных элементов другого view, пока предикат возвращает false
(шаблон класса) (объект адаптера диапазона)
ranges::drop_viewviews::drop
(C++20)
view, состоящий из элементов другого view, пропуская первые N элементов
(шаблон класса) (объект адаптера диапазона)
ranges::drop_while_viewviews::drop_while
(C++20)
view, состоящий из элементов другого view, пропуская начальную подпоследовательность элементов до первого элемента, где предикат возвращает false
(шаблон класса) (объект адаптера диапазона)
ranges::join_viewviews::join
(C++20)
view, состоящий из последовательности, полученной путем уплощения view range
(шаблон класса) (объект адаптера диапазона)
ranges::split_viewviews::split
(C++20)
view над поддиапазонами, полученными путем разделения другого view с помощью разделителя
(шаблон класса) (объект адаптера диапазона)
ranges::lazy_split_viewviews::lazy_split
(C++20)
view над поддиапазонами, полученными путем разделения другого view с помощью разделителя
(шаблон класса) (объект адаптера диапазона)
views::counted
(C++20)
создает поддиапазон из итератора и счетчика
(объект точки кастомизации)
ranges::common_viewviews::common
(C++20)
преобразует view в common_range
(шаблон класса) (объект адаптера диапазона)
ranges::reverse_viewviews::reverse
(C++20)
view, итерирующийся по элементам другого двунаправленного диапазона в обратном порядке
(шаблон класса) (объект адаптера диапазона)
ranges::elements_viewviews::elements
(C++20)
берет view, состоящий из tuple-like значений и числа N, и производит view N-го элемента каждой кортежи
(шаблон класса) (объект адаптера диапазона)
ranges::keys_viewviews::keys
(C++20)
берет view, состоящий из парных значений, и производит view первых элементов каждой пары
(шаблон класса) (объект адаптера диапазона)
ranges::values_viewviews::values
(C++20)
берет view, состоящий из парных значений, и производит view вторых элементов каждой пары
(шаблон класса) (объект адаптера диапазона)
END_OF_DOCUMENT_MARKER
ranges::enumerate_viewviews::enumerate
(C++23)
a view that maps each element of adapted sequence to a tuple of both the element's position and its value
(class template) (range adaptor object)
ranges::zip_viewviews::zip
(C++23)
a view consisting of tuples of references to corresponding elements of the adapted views
(class template) (customization point object)
ranges::zip_transform_viewviews::zip_transform
(C++23)
a view consisting of tuples of results of application of a transformation function to corresponding elements of the adapted views
(class template) (customization point object)
ranges::adjacent_viewviews::adjacent
(C++23)
a view consisting of tuples of references to adjacent elements of the adapted view
(class template) (range adaptor object)
ranges::adjacent_transform_viewviews::adjacent_transform
(C++23)
a view consisting of tuples of results of application of a transformation function to adjacent elements of the adapted view
(class template) (range adaptor object)
ranges::join_with_viewviews::join_with
(C++23)
a view consisting of the sequence obtained from flattening a view of ranges, with the delimiter in between elements
(class template) (range adaptor object)
ranges::slide_viewviews::slide
(C++23)
a view whose Mth element is a view over the Mth through (M + N - 1)th elements of another view
(class template) (range adaptor object)
ranges::chunk_viewviews::chunk
(C++23)
a range of views that are N-sized non-overlapping successive chunks of the elements of another view
(class template) (range adaptor object)
ranges::chunk_by_viewviews::chunk_by
(C++23)
splits the view into subranges between each pair of adjacent elements for which the given predicate returns false
(class template) (range adaptor object)
ranges::as_const_viewviews::as_const
(C++23)
converts a view into a constant_range
(class template) (range adaptor object)
ranges::as_rvalue_viewviews::as_rvalue
(C++23)
a view of a sequence that casts each element to an rvalue
(class template) (range adaptor object)
ranges::stride_viewviews::stride
(C++23)
a view consisting of elements of another view, advancing over N elements at a time
(class template) (range adaptor object)
ranges::cartesian_product_viewviews::cartesian_product
(C++23)
a view consisting of tuples of results calculated by the n-ary cartesian product of the adapted views
(class template) (customization point object)

Генераторы диапазонов

Определено в заголовке <generator>
Определено в пространстве имён std
generator
(C++23)
A view that represents synchronous coroutine generator
(class template)

Вспомогательные элементы

Объекты адаптеров диапазонов

См. RangeAdaptorObject (РАО).

Объекты адаптеров диапазонов с замыканием

См. RangeAdaptorClosureObject (РАКО).

Объекты точек кастомизации

См. Объект точки кастомизации (ОТПК).

Обёртка с присваиванием

Некоторые адаптеры диапазонов оборачивают свои элементы или объекты функций с помощью copyable-box(до C++23)movable-box(с C++23). Обёртка дополняет оборачиваемый объект возможностью присваивания по мере необходимости.

Кэш без распространения

Некоторые адаптеры диапазонов определяются с помощью класса-шаблона без распространения, который ведет себя почти точно так же, как std::optional<T> (см. описание различий).

Помощники объектов точек кастомизации

template< ranges::input_range R >
constexpr auto& /*possibly-const-range*/(R& r) {
  if constexpr (ranges::constant_range<const R> && !ranges::constant_range<R>) {
    return const_cast<const R&>(r);
  } else {
    return r;
  }
}
(1) (только для иллюстрации*)
template< class T >
constexpr auto /*as-const-pointer*/( const T* p ) {
  return p;
}
(2) (только для иллюстрации*)

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

1) /*possibly-const-range*/ возвращает диапазон с модификатором const r если это глубоко-постоянный диапазон; в противном случае, возвращает r без преобразования.
END_OF_DOCUMENT_MARKER
2) /*as-const-pointer*/ возвращает указатель на объект константного типа.

Помощники адаптеров диапазонов

template< class F, class Tuple >
constexpr auto /*tuple-transform*/( F&& f, Tuple&& tuple ) {
  return std::apply([&]<class... Ts>(Ts&&... elements) {
    return std::tuple<std::invoke_result_t<F&, Ts>...>(
      std::invoke(f, std::forward<Ts>(elements))...
    );
  }, std::forward<Tuple>(tuple));
}
(1) (только для примера*)
template< class F, class Tuple >
constexpr void /*tuple-for-each*/( F&& f, Tuple&& tuple ) {
  std::apply([&]<class... Ts>(Ts&&... elements) {
    (static_cast<void>(std::invoke(f, std::forward<Ts>(elements))), ...);
  }, std::forward<Tuple>(tuple));
}
(2) (только для примера*)
template< class T >
constexpr T& /*as-lvalue*/( T&& t ) {
  return static_cast<T&>(t);
}
(3) (только для примера*)

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

1) /*tuple-transform*/ возвращает новую кортеж, построенную путём применения f к каждому элементу tuple.
2) /*tuple-for-each*/ применяет f к каждому элементу tuple и ничего не возвращает.
3) /*as-lvalue*/ передаёт rvalue t как lvalue.

Вспомогательные концепции

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

template< class R >
  concept /*simple-view*/ =
    ranges::view<R> && ranges::range<const R> &&
    std::same_as<ranges::iterator_t<R>, ranges::iterator_t<const R>> &&
    std::same_as<ranges::sentinel_t<R>, ranges::sentinel_t<const R>>;
(1) (только для примера*)
template< class I >
  concept /*has-arrow*/ =
    ranges::input_iterator<I> &&
    (std::is_pointer_v<I> || requires(I i) { i.operator->(); });
(2) (только для примера*)
template< class T, class U >
  concept /*different-from*/ =
    !std::same_as<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
(3) (только для примера*)
template< class R >
  concept /*range-with-movable-references*/ =
    ranges::input_range<R> &&
    std::move_constructible<ranges::range_reference_t<R>> &&
    std::move_constructible<ranges::range_rvalue_reference_t<R>>;
(4) (только для примера*)

Примечания

Макрос проверки наличия функции Значение Std Функция
__cpp_lib_generator 202207L (C++23) std::generator – синхронный генератор корутин для диапазонов
__cpp_lib_ranges 201911L (C++20) Библиотека диапазонов и ограниченные алгоритмы
202106L (C++20)
(DR)
Не-инициализируемые по умолчанию представления
202110L (C++20)
(DR)
Представления с владением
202202L (C++23) std::ranges::range_adaptor_closure
202207L (C++23) Смягчение требований к адаптерам диапазонов, чтобы разрешить типы, которые можно только перемещать
202211L (C++23) Удаление перегрузок «ядовитых пилюль» (P2602) в ranges::begin и т.д.
__cpp_lib_ranges_as_const 202207L (C++23) std::const_iterator, std::ranges::as_const_view
__cpp_lib_ranges_as_rvalue 202207L (C++23) std::ranges::as_rvalue_view
__cpp_lib_ranges_cartesian_product 202207L (C++23) std::ranges::cartesian_product_view
__cpp_lib_ranges_chunk 202202L (C++23) std::ranges::chunk_view
__cpp_lib_ranges_chunk_by 202202L (C++23) std::ranges::chunk_by_view
__cpp_lib_ranges_enumerate 202302L (C++23) std::ranges::enumerate_view
__cpp_lib_ranges_join_with 202202L (C++23) std::ranges::join_with_view
__cpp_lib_ranges_repeat 202207L (C++23) std::ranges::repeat_view
__cpp_lib_ranges_slide 202202L (C++23) std::ranges::slide_view
__cpp_lib_ranges_stride 202207L (C++23) std::ranges::stride_view
__cpp_lib_ranges_to_container 202202L (C++23) std::ranges::to
__cpp_lib_ranges_zip 202110L (C++23) std::ranges::zip_view,
std::ranges::zip_transform_view,
std::ranges::adjacent_view,
std::ranges::adjacent_transform_view

Пример

#include <iostream>
#include <ranges>
 
int main()
{
    auto const ints = {0, 1, 2, 3, 4, 5};
    auto even = [](int i) { return 0 == i % 2; };
    auto square = [](int i) { return i * i; };
 
    // the "pipe" syntax of composing the views:
    for (int i : ints | std::views::filter(even) | std::views::transform(square))
        std::cout << i << ' ';
 
    std::cout << '\n';
 
    // a traditional "functional" composing syntax:
    for (int i : std::views::transform(std::views::filter(ints, even), square))
        std::cout << i << ' ';
}

Вывод:

0 4 16
0 4 16

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

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

DR Применён к Поведение при публикации Правильное поведение
LWG 3509 C++20 не было ясно, как объекты адаптеров диапазонов связывают аргументы, следующие за ними они связаны по значению

См. также

  • Библиотека итераторов
  • Ограниченные алгоритмы

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

Spec-Zone.ru

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