Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Iterator Facade and Adaptor

Boost , ,

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Iterator Facade and Adaptor

Author: Дэвид Абрахамс, Джереми Сик, Томас Витт
Contact: Итераторы играют важную роль в современном программировании на C++. Итератор — это центральная абстракция алгоритмов Стандартной библиотеки, позволяющая повторно использовать алгоритмы в самых разных контекстах. C++ Стандартная библиотека содержит широкий спектр полезных итераторов. Каждый стандартный контейнер поставляется с постоянными и изменяемыми итераторами.2, а также обратные версии тех же итераторов, которые пересекают контейнер в противоположном направлении. Стандарт также поставляетistream_iteratorиostream_iteratorдля чтения и записи в потокивставить_iterator,front_insert_iteratorиback_insert_iteratorдля вставки элементов в контейнеры иraw_storage_iteratorдля инициализации сырой памяти.

Несмотря на множество итераторов, поставляемых Стандартной библиотекой, очевидные и полезные итераторы отсутствуют, а создание новых типов итераторов по-прежнему является общей задачей для программистов C++. Литература документирует некоторые из них, например line_iteratorи Constant_iterator.. Абстракция итератора настолько сильна, что мы ожидаем, что программистам всегда придется изобретать новые типы итераторов.

Хотя легко создать итераторы, которыепочтисоответствуют стандарту, требования итератора содержат тонкости, которые могут сделать создание итератора, которыйна самом делесоответствует довольно сложно. Кроме того, интерфейс итератора богат, содержит множество операторов, которые технически избыточны и утомительны для реализации. Для автоматизации повторяющейся работы по построению итераторов мы предлагаемiterator_facade, шаблон базового класса итератора, который обеспечивает богатый интерфейс стандартных итераторов и делегирует его реализацию членским функциям производного класса. В дополнение к уменьшению количества кода, необходимого для создания итератора,iterator_facadeтакже обеспечивает обнаружение ошибок в компиляции. Ошибки реализации итератора, которые часто остаются незамеченными, превращаются в ошибки времени компиляции, потому что реализация производного класса должна соответствовать ожиданиямiterator_facade.

Общая схема построения итератора — адаптация одного итератора к формированию нового. Функциональность итератора состоит из четырех ортогональных аспектов: обход, опосредование, сравнение равенства и измерение расстояния. Адаптация старого итератора для создания нового часто экономит работу, потому что можно повторно использовать один аспект функциональности при переопределении другого. Например, Стандарт предоставляетreverse_iterator, который адаптирует любой Двунаправленный итератор, инвертируя его направление прохождения. Как и в случае простых итераторов, адаптеры итераторов, определенные вне стандарта, стали обычным явлением в литературе:

  • Проверенный итердобавляет проверку границ к существующему итератору.
  • Итераторы библиотеки шаблонов просмотра, которые адаптируют контейнеры, сами являются адаптерами по сравнению с базовыми итераторами.
  • Умные итераторыадаптирует поведение итератора, применяя объект функции к объекту, на который ссылаются, и возвращая результат.
  • Настраиваемые итераторы, в которых перечислены различные типы адаптеров.
  • Составные итераторы, которые получают доступ к срезу из контейнера контейнеров.
  • Несколько адаптеров итератора от MTL. MTL содержит шагающий итератор, где каждый вызов коператору++()перемещает итератор вперед по некоторому постоянному фактору и масштабированному итератору, который умножает отложенное значение на некоторую постоянную.
[1]Мы используем термин «концепция» для обозначения набора требований, которым должен удовлетворять тип для использования с конкретным параметром шаблона.
[2]Термин мутабельный итератор относится к итераторам над объектами, которые могут быть изменены путем присвоения отнесенному итератору, в то время как постоянный итератор относится к итераторам над объектами, которые не могут быть изменены.

Чтобы удовлетворить потребность в конструировании адаптеров, мы предлагаем шаблон классаiterator_adaptor. Обоснованияiterator_adaptorслужат базовыми классами для новых итераторов, обеспечивая по умолчанию поведение пересылки всех операций на базовый итератор. Пользователь может выборочно заменить эти функции в классе производных итераторов. Это предложение также включает в себя ряд более специализированных адаптеров, таких какtransform_iterator, который применяет некоторые функции, определенные пользователем во время отсчета итератора.

Impact on the Standard

Это предложение является чисто дополнением к стандартной библиотеке C++. Тем не менее, обратите внимание, что это предложение основано на предложении новых концепций итератора.

Design

Iterator Concepts

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

Это предложение не зависит строго от предложенияn1550, поскольку существует прямое сопоставление между новыми и старыми категориями. Это предложение можно было бы переформулировать с помощью этого сопоставления, если быn1550не было принято.

Interoperability

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

Выпуск179касается того, что мутируемые типы контейнерных итераторов должны быть только конвертируемыми в соответствующие типы постоянных итераторов, но объекты этих типов не обязаны взаимодействовать в выражениях сравнения или вычитания. Эта ситуация утомительна на практике и не соответствует тому, как работают типы. В этом предложении реализовано предложенное решение о выпуске179, как и в большинстве стандартных реализаций библиотек в настоящее время. Другими словами, если итератор типа А имеет неявное или определенное пользователем преобразование в итератор типа В, типы итератора являются взаимодействующими и доступен обычный набор операторов.

Проблема280касается нынешнего отсутствия совместимости между типами реверсивных итераторов. Предлагаемый новый шаблон reverse_iterator решает проблемы, поднятые в 280 году. Он обеспечивает желаемую совместимость без введения нежелательных перегрузок.

Iterator Facade

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

  • отсрочка
  • возрастание
  • декремент
  • сравнение равенства
  • движение случайного доступа
  • измерение расстояния

В дополнение к вышеперечисленным видам поведения, основные элементы интерфейса включают связанные типы, подвергаемые через итераторы признакам:value_type,reference,difference_typeиiterator_category.

Фасад итератора использует Curiously Recurring Template Pattern (CRTP)[Cop95], чтобы пользователь мог указать поведениеiterator_facadeв производном классе. Бывшие проекты использовали объекты политики для определения поведения, но этот подход был отброшен по нескольким причинам:

  1. Создание и возможное копирование объекта политики может создать накладные расходы, которых можно избежать при нынешнем подходе.
  2. Подход «объект политики» не позволяет создавать пользовательские конструкторы на созданных типах итераторов, что является существенной особенностью, еслиiterator_facadeследует использовать в других вариантах осуществления библиотеки.
  3. Без использования CRTP стандартное требование оператора итератора++возвращает сам тип итератора, что означает, что все итераторы, построенные с библиотекой, должны быть специализациямиiterator_facade<...>, а не чем-то более описательным, какdirect_iterator. Для создания новых параметризованных итераторов потребуются громоздкие метафункции генератора типа, а отдельный слойитератора_адапторабудет невозможен.

Usage

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

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

Expression Effects
i.dereference() Доступ к значению, указанному
i.equal(j) Сравните для равенства сj
i.increment() Продвижение на одну позицию
i.decrement() Отступление на одну позицию
i.advance(n) nположения
i.distance_to(j) Измерить расстояние доj

В дополнение к реализации основных функций интерфейса итератор, полученный изiterator_facade, обычно определяет несколько конструкторов. Чтобы смоделировать любую из стандартных концепций итератора, итератор должен иметь конструктор копий. Кроме того, если тип итератораXпредназначен для автоматического взаимодействия с другим типом итератораY(как с постоянными и изменчивыми итераторами), то должно быть неявное преобразование изXвYили изYвX(но не оба), как правило, реализованное в качестве конструктора преобразования. Наконец, если итератор предназначен для моделирования итератора переднего поворота или более усовершенствованной концепции итератора, требуется конструктор по умолчанию.

Iterator Core Access

iterator_facadeи реализации оператора должны иметь возможность доступа к основным функциям-членам в производном классе. Публикация основных функций-членов раскрывает пользователю детали реализации. Используемый здесь дизайн гарантирует, что детали реализации не отображаются в публичном интерфейсе производного типа итератора.

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

В наивной реализации сохранение в тайне основных функций членов производного класса потребует от него предоставления дружбыiterator_facadeи каждому из семи операторов. Чтобы уменьшить бремя ограничения доступа, предоставляетсяiterator_core_access, класс, который действует как шлюз к функциям основного члена в классе производного итератора. Автору производного класса нужно только предоставить дружбуiterator_core_access, чтобы его основные функции члена были доступны библиотеке.

iterator_core_accessобычно реализуется в виде пустого класса, содержащего только частные статические функции-члены, которые вызывают функции-ядра итератора. Однако нет необходимости стандартизировать протокол шлюза. Обратите внимание, что даже еслиитератор_core_accessиспользует публичные функции-члены, это не откроет лазейку безопасности, поскольку каждая функция-ядро сохраняет инварианты итератора.

operator[]

Оператор индексации для обобщенного итератора представляет особые проблемы. Итератор случайного доступаоператортребуется только вернуть что-то конвертируемое в егозначение_тип. Требование, чтобы он возвращал значение l, исключало бы в настоящее время законные итераторы случайного доступа, которые содержат указанное значение в элементе данных (например,подсчёт_iterator), потому что* (p+n)является ссылкой на временный итераторp+n, который разрушается, когдаоператор []возвращается.

Письменные итераторы, построенные с помощьюiterator_facade, реализуют семантику, требуемую предпочтительным разрешениемвыпуска 299и принятую предложениемn1550: результатp[n]является объектом, конвертируемым в итераторзначение_тип, иp [n]xэквивалентен* [p+=x(Примечание: Этот объект результата может быть реализован в качестве прокси, содержащего копиюp+n. Этот подход будет работать должным образом для любого итератора случайного доступа независимо от других деталей его реализации. Пользователь, который знает больше о реализации своего итератора, может свободно реализовать оператора, который возвращает значение l в классе производного итератора; он будет скрывать тот, который поставляетсяiterator_facadeот клиентов своего итератора.

operator->

Тип ссылкичитаемого итератора (и сегодняшнего итератора ввода) на самом деле не обязательно должен быть эталоном, если он конвертируем в значениеитератора. Однако, когдазначение_типявляется классом, все равно должна быть возможность доступа к членам черезоператора->. Поэтому итератор, чейэталонныйтип фактически не является эталонным, должен возвращать прокси-сервер, содержащий копию указанной величины от егооператора->.

Типы возврата дляiterator_facade'sоператора->иоператора []явно не указаны. Вместо этого эти типы описаны в терминах набора требований, которые должны быть удовлетворены реализациейiterator_facade.

[Cop95][Coplien, 1995] Coplien, J., Curiously Recurring Template Patterns, C++ Report, February 1995, pp.

Iterator Adaptor

Шаблон классаiterator_adaptorадаптирует некоторыйБазовый3тип для создания нового итератора. Обоснованияiterator_adaptorполучены из соответствующего инстанциированияiterator_facadeи реализуют основные модели поведения с точки зренияBaseтипа. По сути,iterator_adaptorпросто перенаправляет все операции на экземпляр типаBase, который он хранит в качестве члена.

[3]Термин «база» здесь не относится к базовому классу и не подразумевает использование производных. Мы последовали примеру стандартной библиотеки, которая предоставляет функцию base() для доступа к объекту итератораадаптера reverse_iterator.

Пользовательiterator_adaptorсоздает класс, полученный из инстанциацииiterator_adaptor, а затем выборочно переопределяет некоторые из основных функций-членов, описанных в таблице основных требованийiterator_facade. ТипBaseне должен удовлетворять всем требованиям к итератору; ему требуется только поддержка операций, используемых основными функциями интерфейсаiterator_adaptor, которые не были переопределены в производном классе пользователя.

Несколько параметров шаблонаiterator_adaptorпо умолчаниюиспользуют_default. Это позволяет пользователю использовать параметр по умолчанию, даже если он хочет указать параметр позже в списке параметров. Также по умолчанию для соответствующих связанных типов несколько сложны, поэтому для их вычисления требуется метапрограммирование, иuse_defaultможет помочь упростить реализацию. Наконец, идентификатор типаuse_defaultне остается неуказанным, поскольку спецификация помогает подчеркнуть, чтоСсылочныйпараметр шаблона не всегда может быть идентичен ссылочномутипу итератораи не позволит пользователям совершать ошибки на основе этого предположения.

Specialized Adaptors

Это предложение также содержит несколько примеров специализированных адаптеров, которые были легко реализованы с использованиемiterator_adaptor:

  • direct_iterator, который повторяется над итераторами, указателями или умными указателями и применяет дополнительный уровень отсчета.
  • Новыйreverse_iterator, который переворачивает направление движения базового итератора, позволяя при этом адаптировать постоянные и изменяемые итераторы для взаимодействия ожидаемыми способами (в отличие от тех, что в большинстве реализаций C++98).
  • Transform_iterator, который применяет объект функции, определяемый пользователем, к базовым значениям при снятии ссылки.
  • filter_iterator, который обеспечивает вид диапазона итератора, в котором некоторые элементы базового диапазона пропущены.
  • counting_iterator, который адаптирует любой инкрементируемый тип (например, целые числа, итераторы) таким образом, что инкрементирование/декрементирование адаптированного итератора и отступление от него производят последовательные значения базового типа.
  • function_output_iterator, что облегчает создание пользовательских итераторов вывода.

Основываясь на примерах в библиотеке Boost, пользователи создали много новых адаптеров, среди которых адаптер перестановки, который применяет некоторую перестановку к итератору случайного доступа, и шагающий адаптер, который адаптирует итератор случайного доступа, умножая свою единицу движения на постоянный фактор. Кроме того, библиотека Boost Graph Library (BGL) использует адаптеры итераторов для адаптации других графовых библиотек, таких как LEDAи Stanford GraphBase, к интерфейсу BGL (для которого требуются итераторы, соответствующие стандарту C++).

Proposed Text

Header <iterator_helper> synopsis [lib.iterator.helper.synopsis]

struct use_default;
struct iterator_core_access { /* implementation detail */ };
template <
    class Derived
  , class Value
  , class CategoryOrTraversal
  , class Reference  = Value&
  , class Difference = ptrdiff_t
>
class iterator_facade;
template <
    class Derived
  , class Base
  , class Value      = use_default
  , class CategoryOrTraversal  = use_default
  , class Reference  = use_default
  , class Difference = use_default
>
class iterator_adaptor;
template <
    class Iterator
  , class Value = use_default
  , class CategoryOrTraversal = use_default
  , class Reference = use_default
  , class Difference = use_default
>
class indirect_iterator;
template <class Dereferenceable>
struct pointee;
template <class Dereferenceable>
struct indirect_reference;
template <class Iterator>
class reverse_iterator;
template <
    class UnaryFunction
  , class Iterator
  , class Reference = use_default
  , class Value = use_default
>
class transform_iterator;
template <class Predicate, class Iterator>
class filter_iterator;
template <
    class Incrementable
  , class CategoryOrTraversal  = use_default
  , class Difference = use_default
>
class counting_iterator;
template <class UnaryFunction>
class function_output_iterator;

Iterator facade [lib.iterator.facade]

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

Class template iterator_facade

template <
    class Derived
  , class Value
  , class CategoryOrTraversal
  , class Reference  = Value&
  , class Difference = ptrdiff_t
>
class iterator_facade {
 public:
    typedef remove_const<Value>::type value_type;
    typedef Reference reference;
    typedef Value* pointer;
    typedef Difference difference_type;
    typedef /* see below */ iterator_category;
    reference operator*() const;
    /* see below */ operator->() const;
    /* see below */ operator[](difference_type n) const;
    Derived& operator++();
    Derived operator++(int);
    Derived& operator--();
    Derived operator--(int);
    Derived& operator+=(difference_type n);
    Derived& operator-=(difference_type n);
    Derived operator-(difference_type n) const;
 protected:
    typedef iterator_facade iterator_facade_;
};
// Comparison operators
template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type // exposition
operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
            iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
            iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
           iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
            iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
           iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
            iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
// Iterator difference
template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
/* see below */
operator-(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
          iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
// Iterator addition
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
                   typename Derived::difference_type n);
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (typename Derived::difference_type n,
                   iterator_facade<Dr,V,TC,R,D> const&);

The iterator_category member of iterator_facade is

iterator-category(CategoryOrTraversal, value_type, reference)

гдеитератор-категорияопределена следующим образом:

iterator-category(C,R,V) :=
   if (C is convertible to std::input_iterator_tag
       || C is convertible to std::output_iterator_tag
   )
       return C
   else if (C is not convertible to incrementable_traversal_tag)
       the program is ill-formed
   else return a type X satisfying the following two constraints:
      1. X is convertible to X1, and not to any more-derived
         type, where X1 is defined by:
           if (R is a reference type
               && C is convertible to forward_traversal_tag)
           {
               if (C is convertible to random_access_traversal_tag)
                   X1 = random_access_iterator_tag
               else if (C is convertible to bidirectional_traversal_tag)
                   X1 = bidirectional_iterator_tag
               else
                   X1 = forward_iterator_tag
           }
           else
           {
               if (C is convertible to single_pass_traversal_tag
                   && R is convertible to V)
                   X1 = input_iterator_tag
               else
                   X1 = C
           }
      2. category-to-traversal(X) is convertible to the most
         derived traversal tag type to which X is also
         convertible, and not to any more-derived traversal tag
         type.

[Примечание: намерение состоит в том, чтобы позволитьiterator_categoryбыть одним из пяти исходных тегов категории, когда конвертируемость в один из тегов обхода не добавит информации]

Шаблонenable_if_interoperable, используемый выше, предназначен для экспозиции. Операторы-члены должны находиться только в наборе перегрузок при условии, что производные типыDr1иDr2являются взаимодействующими, что означает, что по меньшей мере один из типов является конвертируемым в другой. Подходпозволяет_if_interoperableиспользовать SFINAE для вывода операторов из набора перегрузок, когда типы не совместимы. Операторы должны вести себятак, как есливключить_if_интероперабельностьбыло определено:

template <bool, typename> enable_if_interoperable_impl
{};
template <typename T> enable_if_interoperable_impl<true,T>
{ typedef T type; };
template<typename Dr1, typename Dr2, typename T>
struct enable_if_interoperable
  : enable_if_interoperable_impl<
        is_convertible<Dr1,Dr2>::value || is_convertible<Dr2,Dr1>::value
      , T
    >
{};

iterator_facade Requirements

В следующей таблице описаны типичные действительные выражения поитератор_фасад'sПроизводныйпараметр, в зависимости от концепции(ей) итератора, которую он будет моделировать. Операции в первой колонке должны быть доступны для членских функций классаiterator_core_access. Кроме того,static_cast(iterator_facade*)должны быть хорошо сформированы.

В приведенной ниже таблицеFaaX,bиcconst,nF::difference_type,yявляется постоянным объектом однопроходного итератора типа, взаимодействующего сX, иzzявляется постоянным объектом случайного доступа, пересекающегося с итератором типа

iterator_facade Core Operations

Expression Return Type Assertion/Note Used to implement Iterator Concept(s)
c.dereference() F:: ссылка   Читаемый итератор, письменный итератор
c.equal(y) конвертируемый в bool сиуотносятся к одной и той же позиции. Итератор Single Pass
a.increment() неиспользованный   Необычный итератор
a.decrement() неиспользованный   Двунаправленный итератор поворотов
a.advance(n) неиспользованный   Случайный доступ Traversal Iterator
c.distance_to(z) конвертируемый вF::difference_type расстояние (c,X(z)]. Случайный доступ Traversal Iterator

iterator_facade operations

Операции в этом разделе описаны в терминах операций на базовом интерфейсе.Получено, которое может быть недоступным (т.е. частным). Реализация должна обеспечивать доступ к этим операциям через функции-члены классаiterator_core_access.

эталоноператор*()const;

Returns:static_cast<Derived const*>(this)->dereference()

оператор->()const;(см.ниже)

Returns:

If reference is a reference type, an object of type pointer equal to:

&static_cast<Derived const*>(this)->dereference()

Otherwise returns an object of unspecified type such that, (*static_cast<Derived const*>(this))->m is equivalent to (w = **static_cast<Derived const*>(this), w.m) for some temporary object w of type value_type.

unspecified operator[](difference_type n) const;

Returns:an object convertible to value_type. For constant objects v of type value_type, and n of type difference_type, (*this)[n] = v is equivalent to *(*this + n) = v, and static_cast<value_type const&>((*this)[n]) is equivalent to static_cast<value_type const&>(*(*this + n))

Derived&operator++();

Effects:
static_cast<Derived*>(this)->increment();
return *static_cast<Derived*>(this);

Выводитсяоператор++(int);

Effects:
Derived tmp(static_cast<Derived const*>(this));
++*this;
return tmp;

Производный &оператор--();

Effects:
static_cast<Derived*>(this)->decrement();
return *static_cast<Derived*>(this);

Производныйоператор - (int);

Effects:
Derived tmp(static_cast<Derived const*>(this));
--*this;
return tmp;

Производный &оператор +=(разница_типn);

Effects:
static_cast<Derived*>(this)->advance(n);
return *static_cast<Derived*>(this);

Производный &оператор-=(разница_типn);

Effects:
static_cast<Derived*>(this)->advance(-n);
return *static_cast<Derived*>(this);

Выводитсяоператор-(различие_типn)const;

Effects:
Derived tmp(static_cast<Derived const*>(this));
return tmp -= n;
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
                   typename Derived::difference_type n);
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (typename Derived::difference_type n,
                   iterator_facade<Dr,V,TC,R,D> const&);
Effects:
Derived tmp(static_cast<Derived const*>(this));
return tmp += n;
template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
            iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
Returns:

if is_convertible<Dr2,Dr1>::value

then

((Dr1 const&)lhs).equal((Dr2 const&)rhs).

Otherwise,

((Dr2 const&)rhs).equal((Dr1 const&)lhs).

template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
            iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
Returns:

if is_convertible<Dr2,Dr1>::value

then

!((Dr1 const&)lhs).equal((Dr2 const&)rhs).

Otherwise,

!((Dr2 const&)rhs).equal((Dr1 const&)lhs).

template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
           iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
Returns:

if is_convertible<Dr2,Dr1>::value

then

((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0.

Otherwise,

((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0.

template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
            iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
Returns:

if is_convertible<Dr2,Dr1>::value

then

((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0.

Otherwise,

((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0.

template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
           iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
Returns:

if is_convertible<Dr2,Dr1>::value

then

((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0.

Otherwise,

((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0.

template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
            iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
Returns:

if is_convertible<Dr2,Dr1>::value

then

((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0.

Otherwise,

((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0.

template <class Dr1, class V1, class TC1, class R1, class D1,
          class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,difference>::type
operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
           iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
Return Type:

if is_convertible<Dr2,Dr1>::value

then

difference shall be iterator_traits<Dr1>::difference_type.

Otherwise

difference shall be iterator_traits<Dr2>::difference_type

Returns:

if is_convertible<Dr2,Dr1>::value

then

-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs).

Otherwise,

((Dr2 const&)rhs).distance_to((Dr1 const&)lhs).

Iterator adaptor [lib.iterator.adaptor]

Каждая специализация шаблона классаiterator_adaptorпроисходит от специализацииiterator_facade. Основные функции интерфейса, ожидаемыеiterator_facade, реализованы с точки зренияiterator_adaptorбазовогопараметра шаблона. Класс, полученный изiterator_adaptor, обычно переопределяет некоторые основные функции интерфейса для адаптации поведения типаBase. Является ли производная модель класса какой-либо из стандартных концепций итератора зависит от операций, поддерживаемых типомБазаи какие основные функции интерфейсаитератор_фасадпереопределяются в классеПроизводный.

Class template iterator_adaptor

template <
    class Derived
  , class Base
  , class Value               = use_default
  , class CategoryOrTraversal = use_default
  , class Reference           = use_default
  , class Difference = use_default
>
class iterator_adaptor
  : public iterator_facade<Derived, V', C', R', D'> // see details
{
    friend class iterator_core_access;
 public:
    iterator_adaptor();
    explicit iterator_adaptor(Base const& iter);
    typedef Base base_type;
    Base const& base() const;
 protected:
    typedef iterator_adaptor iterator_adaptor_;
    Base const& base_reference() const;
    Base& base_reference();
 private: // Core iterator interface for iterator_facade.
    typename iterator_adaptor::reference dereference() const;
    template <
    class OtherDerived, class OtherIterator, class V, class C, class R, class D
    >
    bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
    void advance(typename iterator_adaptor::difference_type n);
    void increment();
    void decrement();
    template <
        class OtherDerived, class OtherIterator, class V, class C, class R, class D
    >
    typename iterator_adaptor::difference_type distance_to(
        iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
 private:
    Base m_iterator; // exposition only
};

iterator_adaptor requirements

static_cast(iterator_adaptor*)должна быть хорошо сформирована.ОснованиеАргумент должен быть приемлемым и копируемым.

iterator_adaptor base class parameters

V',C',R'иD'параметрыитератора_фасада, используемого в качестве базового класса в резюмеитератора_адапторавыше, определяются следующим образом:

V' = if (Value is use_default)
          return iterator_traits<Base>::value_type
      else
          return Value
C' = if (CategoryOrTraversal is use_default)
          return iterator_traversal<Base>::type
      else
          return CategoryOrTraversal
R' = if (Reference is use_default)
          if (Value is use_default)
              return iterator_traits<Base>::reference
          else
              return Value&
      else
          return Reference
D' = if (Difference is use_default)
          return iterator_traits<Base>::difference_type
      else
          return Difference

iterator_adaptor public operations

iterator_adaptor();

Requires:The Base type must be Default Constructible.
Returns:An instance of iterator_adaptor with m_iterator default constructed.

эксплицитныйитератор_адаптор(Базаconst&итер;

Returns:An instance of iterator_adaptor with m_iterator copy constructed from iter.

Базаconst&база []const;

Returns:m_iterator

iterator_adaptor protected member functions

Базаconst&base_reference()const;

Returns:A const reference to m_iterator.

Base&base_reference();

Returns:A non-const reference to m_iterator.

iterator_adaptor private member functions

имя типаитератор_адаптор:: ссылкассылкаconst;

Returns:*m_iterator
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
Returns:m_iterator == x.base()

voidadvance(имяiterator_adaptor::difference_typen);

Effects:m_iterator += n;

voidincrement();

Effects:++m_iterator;

voiddecrement();

Effects:--m_iterator;
template <
    class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
typename iterator_adaptor::difference_type distance_to(
    iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
Returns:y.base() - m_iterator

Specialized adaptors [lib.iterator.special.adaptors]

enable_if_convertible::typeвыражение, используемое в данном разделе, предназначено для экспозиционных целей. Конструкторы-преобразователи для специализированных адаптеров должны быть только в наборе перегрузок при условии, что объект типаXнеявно конвертируем в объект типаY. Подписи, включающиеenable_if_convertible, должны вести себякак-еслиenable_if_convertibleбыли определены как:

template <bool> enable_if_convertible_impl
{};
template <> enable_if_convertible_impl<true>
{ struct type; };
template<typename From, typename To>
struct enable_if_convertible
  : enable_if_convertible_impl<is_convertible<From,To>::value>
{};

Если выражение, отличное от аргумента по умолчанию, используется для подачи значения параметра функции, тип которого записан в терминахenable_if_convertible, программа плохо сформирована, диагностика не требуется.

Примечание:Подходпозволяетиспользовать SFINAE для вывода конструктора из набора перегрузок, когда типы не являются неявно конвертируемыми. ]

Indirect iterator

indirect_iteratorадаптирует итератор, применяядополнительныйdereference внутриоператора*(). Например, этот адаптер итератора позволяет просматривать контейнер указателей (например,list), как если бы это был контейнер заостренного типа (например,).list.indirect_iteratorзависит от двух вспомогательных признаков,pointeeиindirect_reference, для обеспечения поддержки базовых итераторов, значениекоторыхне является итератором.

Class template pointee

template <class Dereferenceable>
struct pointee
{
    typedef /* see below */ type;
};
Requires:For an object x of type Dereferenceable, *x is well-formed. If ++x is ill-formed it shall neither be ambiguous nor shall it violate access control, and Dereferenceable::element_type shall be an accessible type. Otherwise iterator_traits<Dereferenceable>::value_type shall be well formed. [Note: These requirements need not apply to explicit or partial specializations of pointee]

типопределяется по следующему алгоритму, гдеxявляется объектом типаСсылка:

if ( ++x is ill-formed )
{
    return ``Dereferenceable::element_type``
}
else if (``*x`` is a mutable reference to
         std::iterator_traits<Dereferenceable>::value_type)
{
    return iterator_traits<Dereferenceable>::value_type
}
else
{
    return iterator_traits<Dereferenceable>::value_type const
}

Class template indirect_reference

template <class Dereferenceable>
struct indirect_reference
{
    typedef /* see below */ type;
};
Requires:For an object x of type Dereferenceable, *x is well-formed. If ++x is ill-formed it shall neither be ambiguous nor shall it violate access control, and pointee<Dereferenceable>::type& shall be well-formed. Otherwise iterator_traits<Dereferenceable>::reference shall be well formed. [Note: These requirements need not apply to explicit or partial specializations of indirect_reference]

типопределяется по следующему алгоритму, гдеxявляется объектом типаСсылка:

if ( ++x is ill-formed )
    return ``pointee<Dereferenceable>::type&``
else
    std::iterator_traits<Dereferenceable>::reference

Class template indirect_iterator

template <
    class Iterator
  , class Value = use_default
  , class CategoryOrTraversal = use_default
  , class Reference = use_default
  , class Difference = use_default
>
class indirect_iterator
{
 public:
    typedef /* see below */ value_type;
    typedef /* see below */ reference;
    typedef /* see below */ pointer;
    typedef /* see below */ difference_type;
    typedef /* see below */ iterator_category;
    indirect_iterator();
    indirect_iterator(Iterator x);
    template <
        class Iterator2, class Value2, class Category2
      , class Reference2, class Difference2
    >
    indirect_iterator(
        indirect_iterator<
             Iterator2, Value2, Category2, Reference2, Difference2
        > const& y
      , typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
    );
    Iterator const& base() const;
    reference operator*() const;
    indirect_iterator& operator++();
    indirect_iterator& operator--();
private:
   Iterator m_iterator; // exposition
};

Типы членовdirect_iteratorопределяются в соответствии со следующим псевдокодом, гдеVявляетсяiterator_traits::value_type

if (Value is use_default) then
    typedef remove_const<pointee<V>::type>::type value_type;
else
    typedef remove_const<Value>::type value_type;
if (Reference is use_default) then
    if (Value is use_default) then
        typedef indirect_reference<V>::type reference;
    else
        typedef Value& reference;
else
    typedef Reference reference;
if (Value is use_default) then
    typedef pointee<V>::type* pointer;
else
    typedef Value* pointer;
if (Difference is use_default)
    typedef iterator_traits<Iterator>::difference_type difference_type;
else
    typedef Difference difference_type;
if (CategoryOrTraversal is use_default)
    typedef iterator-category (
        iterator_traversal<Iterator>::type,``reference``,``value_type``
    ) iterator_category;
else
    typedef iterator-category (
        CategoryOrTraversal,``reference``,``value_type``
    ) iterator_category;

indirect_iterator requirements

Выражение*v, гдеvявляется объектомiterator_traits::value_type, должно быть действительным выражением и конвертируемым вэталон.Итератордолжен моделировать концепцию обхода, указаннуюитератор_категория.Значение,Ссылка, иСсылка, иРазницавыбирается таким образом, чтобызначение_тип,ссылкаиразличие_типсоответствовали требованиям, указаннымитератор_категория.

[Примечание: существуют дополнительные требования кiterator_traits::value_type, если параметрне являетсяuse_default, как подразумевается алгоритмом для выведения по умолчанию дляvalue_typeчлена.]

indirect_iterator models

В дополнение к понятиям, указаннымiterator_categoryиiterator_traversal::type, специализацияdirect_iteratorмоделирует следующие понятия, гдеvявляется объектомiterator_traits::value_type:

  • Читаемый итератор, еслиссылка (*v)конвертируется взначение_тип.
  • Записываемый итератор, еслиссылка (*v)=tявляется действительным выражением (гдеtявляется объектом типаindirect_iterator::value_type)
  • Lvalue Iterator, еслиссылкаявляется эталонным типом.

direct_iteratorсовместим сdirect_iteratorтогда и только тогда, когдаXсовместим сY.

indirect_iterator operations

В дополнение к операциям, требуемым концепциями, описанными выше, специализацииdirect_iteratorобеспечивают следующие операции.

direct_iterator();

Requires:Iterator must be Default Constructible.
Effects:Constructs an instance of indirect_iterator with a default-constructed m_iterator.

direct_iterator(Iteratorx);

Effects:Constructs an instance of indirect_iterator with m_iterator copy constructed from x.
template <
    class Iterator2, class Value2, unsigned Access, class Traversal
  , class Reference2, class Difference2
>
indirect_iterator(
    indirect_iterator<
         Iterator2, Value2, Access, Traversal, Reference2, Difference2
    > const& y
  , typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
Requires:Iterator2 is implicitly convertible to Iterator.
Effects:Constructs an instance of indirect_iterator whose m_iterator subobject is constructed from y.base().

Итераторconst&base()const;

Returns:m_iterator

эталоноператор*()const;

Returns:**m_iterator

direct_iterator&operator++();

Effects:++m_iterator
Returns:*this

direct_iterator&operator--();

Effects:--m_iterator
Returns:*this

Reverse iterator

Адаптер обратного итератора итерирует через адаптированный диапазон итератора в противоположном направлении.

Class template reverse_iterator

template <class Iterator>
class reverse_iterator
{
public:
  typedef iterator_traits<Iterator>::value_type value_type;
  typedef iterator_traits<Iterator>::reference reference;
  typedef iterator_traits<Iterator>::pointer pointer;
  typedef iterator_traits<Iterator>::difference_type difference_type;
  typedef /* see below */ iterator_category;
  reverse_iterator() {}
  explicit reverse_iterator(Iterator x) ;
  template<class OtherIterator>
  reverse_iterator(
      reverse_iterator<OtherIterator> const& r
    , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
  );
  Iterator const& base() const;
  reference operator*() const;
  reverse_iterator& operator++();
  reverse_iterator& operator--();
private:
  Iterator m_iterator; // exposition
};

ЕслиИтератормодели Random Access Traversal Iterator и Readable Lvalue Iterator, тоитератор_категорияконвертируется вслучайный_access_iterator_tag. В противном случае, еслиИтератормодели Двунаправленный Траверсальный Итератор и Считываемый Итератор Значения, тоитератор_категорияявляется конвертируемым вдвунаправленный_iterator_tag. В противном случаеитератор_категорияпреобразуется ввходной_iterator_tag.

reverse_iterator requirements

Итератордолжен быть моделью Двунаправленного Траверсального Итератора. Типiterator_traits:: ссылкадолжна быть типа*i, гдеiявляется объектом типаИтератор.

reverse_iterator models

Специализацияreverse_iteratorмоделирует те же концепции обхода итератора и доступа итератора, смоделированные его.Итератораргумент. Кроме того, он может моделировать старые концепции итератора, указанные в следующей таблице:

If I models then reverse_iterator<I> models
Читаемый итератор Lvalue, двунаправленный итератор Traversal Двунаправленный итератор
Написанный итератор Lvalue, двунаправленный поперечный итератор Мутабельный двунаправленный итератор
Читаемый итератор Lvalue, итератор случайного доступа Случайный доступ Traversal Iterator
Итератор случайного доступа ( Random Access Traversal Iterator) Мутабельный итератор случайного доступа

reverse_iteratorсовместим сreverse_iterator, если и только еслиXсовместим сY.

reverse_iterator operations

В дополнение к операциям, требуемым концепциями, смоделированнымиreverse_iterator,reverse_iterator, предусмотрены следующие операции.

reverse_iterator();

Requires:Iterator must be Default Constructible.
Effects:Constructs an instance of reverse_iterator with m_iterator default constructed.

явныйобратный_iterator(Iteratorx);

Effects:Constructs an instance of reverse_iterator with m_iterator copy constructed from x.
template<class OtherIterator>
reverse_iterator(
    reverse_iterator<OtherIterator> const& r
  , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
Requires:OtherIterator is implicitly convertible to Iterator.
Effects:Constructs instance of reverse_iterator whose m_iterator subobject is constructed from y.base().

Итераторconst&base()const;

Returns:m_iterator

эталоноператор*()const;

Effects:
Iterator tmp = m_iterator;
return *--tmp;

reverse_iterator&operator++();

Effects:--m_iterator
Returns:*this

reverse_iterator&operator--();

Effects:++m_iterator
Returns:*this

Transform iterator

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

Class template transform_iterator

template <class UnaryFunction,
          class Iterator,
          class Reference = use_default,
          class Value = use_default>
class transform_iterator
{
public:
  typedef /* see below */ value_type;
  typedef /* see below */ reference;
  typedef /* see below */ pointer;
  typedef iterator_traits<Iterator>::difference_type difference_type;
  typedef /* see below */ iterator_category;
  transform_iterator();
  transform_iterator(Iterator const& x, UnaryFunction f);
  template<class F2, class I2, class R2, class V2>
  transform_iterator(
        transform_iterator<F2, I2, R2, V2> const& t
      , typename enable_if_convertible<I2, Iterator>::type* = 0      // exposition only
      , typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
  );
  UnaryFunction functor() const;
  Iterator const& base() const;
  reference operator*() const;
  transform_iterator& operator++();
  transform_iterator& operator--();
private:
  Iterator m_iterator; // exposition only
  UnaryFunction m_f;   // exposition only
};

ЕслиСсылкаявляетсяuse_default, тоэталончленtransform_iteratorявляетсярезультатом_of::reference>::type]. В противном случаессылкаявляетсяссылка.

Еслизначениеявляетсяuse_default, тозначение_typeчленудалите_cv>::type. В противном случаезначение_типявляетсязначением.

ЕслиИтератормодели Считываемый Итератор Значения и еслиИтератормодели Случайный Доступ Поперечный Итератор, тоитератор_категорияконвертируем вслучайный_access_iterator_tag. В противном случае, еслиИтератормодели Двунаправленный Траверсальный Итератор, тоитератор_категориябинаправленный_iterator_tag.В противном случаеитератор_категорияявляется конвертируемым впередний_iterator_tag.ЕслиИтераторне моделирует Считываемый Lvalue Итератор, тоитератор_категорияявляется конвертируемым ввход_iterator_tag.

transform_iterator requirements

ТипUnaryFunctionдолжен быть уступчивым, копируемым, конструируемым, а выражениеf(*i)должно быть действительным, еслиfявляется объектом типа,iявляется объектом типаИтератор, и где типf(*i)должен бытьрезультатом_of::reference)>::type.

АргументИтератордолжен моделировать читаемый итератор.

transform_iterator models

Полученный в результатеTransform_iteratorмоделирует наиболее совершенную из следующих моделей, которая также смоделированаIterator.

  • Записываемый Lvalue Iterator, еслиTransform_iterator::referenceявляется неконст-ссылкой.
  • Считываемый Lvalue Iterator, еслиTransform_iterator::referenceявляется const reference.
  • Читаемый итератор иначе.

МодельTransform_iteratorявляется наиболее усовершенствованной стандартной концепцией обхода, которая смоделирована.Итератораргумент.

ЕслиTransform_iteratorявляется моделью Readable Lvalue Iterator, то он моделирует следующие оригинальные концепции итератора в зависимости от того, чтоИтератормодели аргументов.

If Iterator models then transform_iterator models
Итератор Single Pass Итератор ввода
Вперед Traversal Iterator Передний итератор
Двунаправленный итератор поворотов Двунаправленный итератор
Случайный доступ Traversal Iterator Случайный доступ Traversal Iterator

Еслипреобразовать_iteratorмодели Writable Lvalue Iterator, то это изменяемый итератор (как определено в старых требованиях к итератору).

Transform_iteratorX,R1,V1>совместим сTransform_iteratorY,R2,V2>, если и только еслиXсовместим сY.

transform_iterator operations

В дополнение к операциям, требуемым концепциями, смоделированнымиTransform_iterator,Transform_iteratorобеспечивает следующие операции.

Transform_iterator();

Returns:An instance of transform_iterator with m_f and m_iterator default constructed.

transform_iterator(Iteratorconst&x,UnaryFunctionf);

Returns:An instance of transform_iterator with m_f initialized to f and m_iterator initialized to x.
template<class F2, class I2, class R2, class V2>
transform_iterator(
      transform_iterator<F2, I2, R2, V2> const& t
    , typename enable_if_convertible<I2, Iterator>::type* = 0      // exposition only
    , typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
);
Returns:An instance of transform_iterator with m_f initialized to t.functor() and m_iterator initialized to t.base().
Requires:OtherIterator is implicitly convertible to Iterator.

UnaryFunctionfunctor()const;

Returns:m_f

Итераторconst&base()const;

Returns:m_iterator

эталоноператор*()const;

Returns:m_f(*m_iterator)

transform_iterator&operator++();

Effects:++m_iterator
Returns:*this

transform_iterator&operator--();

Effects:--m_iterator
Returns:*this

Filter iterator

Адаптер фильтратора создает вид диапазона итератора, в котором некоторые элементы диапазона пропущены. Объект функции предиката контролирует, какие элементы пропущены. Когда предикат применяется к элементу, если он возвращаетистинное, то элемент сохраняется, и если он возвращаетложное, то элемент пропускается. При пропуске элементов адаптер фильтра должен знать, когда остановиться, чтобы избежать прохождения конца базового диапазона. Поэтому фильтрующий итератор построен с парой итераторов, указывающих диапазон элементов в нефильтрованной последовательности для прохождения.

Class template filter_iterator

template <class Predicate, class Iterator>
class filter_iterator
{
 public:
    typedef iterator_traits<Iterator>::value_type value_type;
    typedef iterator_traits<Iterator>::reference reference;
    typedef iterator_traits<Iterator>::pointer pointer;
    typedef iterator_traits<Iterator>::difference_type difference_type;
    typedef /* see below */ iterator_category;
    filter_iterator();
    filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
    filter_iterator(Iterator x, Iterator end = Iterator());
    template<class OtherIterator>
    filter_iterator(
        filter_iterator<Predicate, OtherIterator> const& t
        , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
        );
    Predicate predicate() const;
    Iterator end() const;
    Iterator const& base() const;
    reference operator*() const;
    filter_iterator& operator++();
private:
    Predicate m_pred; // exposition only
    Iterator m_iter;  // exposition only
    Iterator m_end;   // exposition only
};

ЕслиИтератормодели Считываемый Итератор Значения и Двунаправленный Траверсальный Итератор, тоитератор_категорияконвертируется вstd::bidirectional_iterator_tag. В противном случае, еслиИтератормодели Считываемый итератор Lvalue и Итератор переднего хода, тоитератор_категорияявляется конвертируемым вstd::forward_iterator_tag. В противном случаеитератор_категорияявляется конвертируемым вstd::input_iterator_tag.

filter_iterator requirements

АргументИтератордолжен соответствовать требованиям Итератора для чтения и Итератора для одиночного прохода или он должен соответствовать требованиям Итератора ввода.

АргументПредикатадолжен быть приемлемым, копируемым конструируемым, а выражениеp(x)должно быть действительным, еслиpявляется объектом типаПредиката,xявляется объектом типаитератора_traits::value_type, и если типp(x)должен быть конвертируемым вbool.

filter_iterator models

Представления о том, чтомодели фильтра-итераторазависят от того, какие понятияИтератормодели аргументов, как указано в следующих таблицах.

If Iterator models then filter_iterator models
Итератор Single Pass Итератор Single Pass
Вперед Traversal Iterator Вперед Traversal Iterator
Двунаправленный итератор поворотов Двунаправленный итератор поворотов
If Iterator models then filter_iterator models
Читаемый итератор Читаемый итератор
Письменный итератор Письменный итератор
Lvalue итератор Lvalue итератор
If Iterator models then filter_iterator models
Считываемый итератор, Single Pass Iterator Итератор ввода
Читаемый итератор Lvalue, передний итератор Traversal Передний итератор
Lvalue Iterator, Forward Traversal Iterator Мутабельный передний итератор
Переписываемый итератор Lvalue, двунаправленный итератор Мутабельный двунаправленный итератор

filter_iteratorX>совместим сfilter_iteratorY>, если и только еслиXсовместим сY.

filter_iterator operations

В дополнение к этим операциям, требуемым концепциями, которыемодели filter_iterator,фильтр_iteratorобеспечивают следующие операции.

filter_iterator();

Requires:Predicate and Iterator must be Default Constructible.
Effects:Constructs a filter_iterator whose``m_pred``, m_iter, and m_end members are a default constructed.

filter_iterator (Предсказательf,Итераторx,Итераторконец=Итератор());

Effects:Constructs a filter_iterator where m_iter is either the first position in the range [x,end) such that f(*m_iter) == true or else``m_iter == end``. The member m_pred is constructed from f and m_end from end.

filter_iterator (Итераторx,Итераторконец=Итератор());

Requires:Predicate must be Default Constructible and Predicate is a class type (not a function pointer).
Effects:Constructs a filter_iterator where m_iter is either the first position in the range [x,end) such that m_pred(*m_iter) == true or else``m_iter == end``. The member m_pred is default constructed.
template <class OtherIterator>
filter_iterator(
    filter_iterator<Predicate, OtherIterator> const& t
    , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
    );``
Requires:OtherIterator is implicitly convertible to Iterator.
Effects:Constructs a filter iterator whose members are copied from t.

ПредикатПредикат()const;

Returns:m_pred

Итераторконецконст;

Returns:m_end

Итераторconst&base()const;

Returns:m_iterator

эталоноператор*()const;

Returns:*m_iter

filter_iterator&operator++();

Effects:Increments m_iter and then continues to increment m_iter until either m_iter == m_end or m_pred(*m_iter) == true.
Returns:*this

Counting iterator

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

Class template counting_iterator

template <
    class Incrementable
  , class CategoryOrTraversal = use_default
  , class Difference = use_default
>
class counting_iterator
{
public:
    typedef Incrementable value_type;
    typedef const Incrementable& reference;
    typedef const Incrementable* pointer;
    typedef /* see below */ difference_type;
    typedef /* see below */ iterator_category;
    counting_iterator();
    counting_iterator(counting_iterator const& rhs);
    explicit counting_iterator(Incrementable x);
    Incrementable const& base() const;
    reference operator*() const;
    counting_iterator& operator++();
    counting_iterator& operator--();
private:
    Incrementable m_inc; // exposition
};

Если аргументРазницаявляетсяUse_default, тоРазница_typeявляется неопределенным подписанным интегральным типом. Иначеdifference_typeDifference.

итератор_категорияопределяется по следующему алгоритму:

if (CategoryOrTraversal is not use_default)
    return CategoryOrTraversal
else if (numeric_limits<Incrementable>::is_specialized)
    return iterator-category(
        random_access_traversal_tag, Incrementable, const Incrementable&)
else
    return iterator-category(
         iterator_traversal<Incrementable>::type,
         Incrementable, const Incrementable&)
[Note: implementers are encouraged to provide an implementation of
operator- and a difference_type that avoids overflows in the cases where std::numeric_limits<Incrementable>::is_specialized is true.]

counting_iterator requirements

Дополняемыйаргумент должен быть конструктивен и приемлем.

Еслиiterator_categoryконвертируется вforward_iterator_tagилиforward_traversal_tag, то должно быть хорошо сформировано следующее:

Incrementable i, j;
++i;         // pre-increment
i == j;      // operator equal

Еслиiterator_categoryконвертируется вbidirectional_iterator_tagилиbidirectional_traversal_tag, то должно быть также хорошо сформировано следующее выражение:

--i

Еслиiterator_categoryконвертируется вrandom_access_iterator_tagилиrandom_access_traversal_tag, то должно быть также действительным следующее:

counting_iterator::difference_type n;
i += n;
n = i - j;
i < j;

counting_iterator models

СпециализацииCounting_iteratorмодель Readable Lvalue Iterator. Кроме того, они моделируют понятия, соответствующие тегам итератора, к которым ихитератор_категорияявляется конвертируемым. Кроме того, еслиCategoryOrTraversalне являетсяuse_default, тоcounting_iteratorмоделирует концепцию, соответствующую тегу итератораКатегорияПутешествия. В противном случае, еслиnumeric_limits::is_specialized, тоcounting_iteratorмодели Random Access Traversal Iterator. В противном случаеCounting_iteratorмоделирует те же концепции обхода итератора, что и.Невероятный.

Counting_iteratorсовместим сCounting_iterator, если и только еслиXсовместим сY.

counting_iterator operations

В дополнение к операциям, требуемым концепциями, смоделированнымиCounting_iterator,Counting_iteratorобеспечивает следующие операции.

Counting_iterator();

Requires:Incrementable is Default Constructible.
Effects:Default construct the member m_inc.

counting_iteratorconst&rhs;

Effects:Construct member m_inc from rhs.m_inc.

эксплицитныйсчетчик_iterator(Incrementablex);

Effects:Construct member m_inc from x.

эталоноператор*()const;

Returns:m_inc

counting_iterator&operator++();

Effects:++m_inc
Returns:*this

counting_iterator&operator--();

Effects:--m_inc
Returns:*this

const&base()const;

Returns:m_inc

Function output iterator

Адаптер итератора вывода функции облегчает создание пользовательских итераторов вывода. Адаптер выполняет унарную функцию и создает модель Output Iterator. Каждый элемент, назначенный выходному итератору, передается в качестве аргумента унарной функции. Мотивация этого итератора заключается в том, что создание соответствующего выходного итератора нетривиально, особенно потому, что для правильной реализации обычно требуется прокси-объект.

function_output_iterator requirements

UnaryFunctionдолжна быть уступчивой и копируемой.

function_output_iterator models

function_output_iteratorявляется моделью концепций Writable and Incrementable Iterator.

function_output_iterator operations

явнаяфункция_output_iterator(constUnaryFunction&f=UnaryFunction());

Effects:Constructs an instance of function_output_iterator with m_f constructed from f.

оператор*();

Returns:An object r of unspecified type such that r = t is equivalent to m_f(t) for all t.

function_output_iterator&operator++();

Returns:*this

function_output_iterator&operator++(int);

Returns:*this

Статья Iterator Facade and Adaptor раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 17:56:42/0.027690172195435/1