![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Dereference the Iterator pointing into a Container AttributeBoost , Spirit 2.5.2 , Extract Attribute Values to Generate Output from a Container (Karma)
|
![]() | Note |
---|---|
Этот файл заголовка не должен быть включен непосредственно какой-либо пользовательской программой, поскольку он обычно включается другими файлами заголовка Spirit, основанными на его содержании. |
Имя |
---|
boost::spirit::traits |
template <typename Iterator, typename Enable> struct deref_iterator { typedef <unspecified> type; static type call(Iterator& it); };
Параметр |
Описание |
По умолчанию |
---|---|---|
| нет | |
| void |
Notation
Iterator
Тип итератора.
it
Пример итератора типа Итератор
.
C
Тип контейнера, тип итератора которого Итератор
.
Выражение |
Семантика |
---|---|
deref_iterator<Iterator>::type | Оценка результата метафункции по типу, возвращаемому с помощью итератора. |
deref_iterator<Iterator>::call(it) | Верните элемент в контейнер, указанный итератором. Тип возвращаемого значения такой же, как и результат метафункции |
Spirit предопределяет специализацию этой точки настройки для нескольких типов. В следующей таблице перечислены эти типы вместе с типами, возвращаемыми встроенным typedef type
:
Параметры шаблонов |
Семантика |
---|---|
| Результат метафункции |
unused_type
const* | Результат метафункции |
Точка настройки deref_iterator
должна быть реализована для конкретного типа итератора, когда контейнер, к которому принадлежит этот итератор, должен использоваться в качестве атрибута вместо контейнера STL. Он применим только для генераторов (Spirit.Karma). Как правило, он должен быть реализован всякий раз, когда определенный тип итератора принадлежит контейнеру, который должен быть передан в качестве атрибута генератору, обычно подвергающему контейнер STL, C
и если тип контейнера не раскрывает интерфейс контейнера STL (т.е. is_container<C>::type
обычно возвращает mpl::false_
).
Если эта точка настройки реализована, могут потребоваться также следующие другие точки настройки.
Имя |
Когда внедрять |
---|---|
Необходимо реализовать всякий раз, когда тип используется в качестве атрибута контейнера в Karma. | |
traits::container_iterator | Карма: Список ( |
traits::begin_container | Карма: Список ( |
traits::end_container | Карма: Список ( |
Карма: Список ( | |
traits::next_iterator | Карма: Список ( |
Карма: Список ( |
Вот файлы заголовка, необходимые для компиляции примерного кода ниже:
#include <boost/spirit/include/karma.hpp> #include <iostream> #include <vector>
Пример (полный исходный код см. здесь: customize_counter.cpp) использует структуру данных
namespace client { struct counter { // expose the current value of the counter as our iterator typedef int iterator; // expose 'int' as the type of each generated element typedef int type; counter(int max_count) : counter_(0), max_count_(max_count) {} int counter_; int max_count_; }; }
как прямой атрибут генератора List (%
). Этот тип не раскрывает ни один из интерфейсов контейнера STL. Он даже не раскрывает привычную семантику контейнера. Представленные точки настройки создают встречный экземпляр, который увеличивается каждый раз, когда к нему обращаются. Примеры показывают, как включить его использование в качестве атрибута повторяющихся генераторов Karma's.
Чтобы сделать эту структуру данных совместимой, нам нужно специализироваться на нескольких точках настройки атрибутов: ::is_container
, traits::traits
, traits::traits::end_container
. Кроме того, мы специализируемся на одной из точек настройки, связанных с итератором: признаков ::deref_iterator
.
// All specializations of attribute customization points have to be placed into // the namespace boost::spirit::traits. // // Note that all templates below are specialized using the 'const' type. // This is necessary as all attributes in Karma are 'const'. namespace boost { namespace spirit { namespace traits { // The specialization of the template 'is_container<>' will tell the // library to treat the type 'client::counter' as a container providing // the items to generate output from. template <> struct is_container<client::counter const> : mpl::true_ {}; // The specialization of the template 'container_iterator<>' will be // invoked by the library to evaluate the iterator type to be used // for iterating the data elements in the container. template <> struct container_iterator<client::counter const> { typedef client::counter::iterator type; }; // The specialization of the templates 'begin_container<>' and // 'end_container<>' below will be used by the library to get the iterators // pointing to the begin and the end of the data to generate output from. // These specializations respectively return the initial and maximum // counter values. // // The passed argument refers to the attribute instance passed to the list // generator. template <> struct begin_container<client::counter const> { static client::counter::iterator call(client::counter const& c) { return c.counter_; } }; template <> struct end_container<client::counter const> { static client::counter::iterator call(client::counter const& c) { return c.max_count_; } }; }}}
// All specializations of attribute customization points have to be placed into // the namespace boost::spirit::traits. namespace boost { namespace spirit { namespace traits { // The specialization of the template 'deref_iterator<>' will be used to // dereference the iterator associated with our counter data structure. // Since we expose the current value as the iterator we just return the // current iterator as the return value. template <> struct deref_iterator<client::counter::iterator> { typedef client::counter::type type; static type call(client::counter::iterator const& it) { return it; } }; }}}
Последний фрагмент кода показывает пример с использованием экземпляра структуры данных клиент::счетчик
для генерации вывода из Списка (%
) генератора:
// use the instance of a 'client::counter' instead of a STL vector client::counter count(4); std::cout << karma::format(karma::int_ % ", ", count) << std::endl; // prints: '0, 1, 2, 3'
Как вы можете видеть, специализации для точек настройки, как определено выше, обеспечивают бесшовную интеграцию пользовательской структуры данных без необходимости изменения формата вывода или самого генератора.
Для других примеров использования точки настройки deref_iterator
См. здесь: use_as_container.
Статья Dereference the Iterator pointing into a Container Attribute раздела Spirit 2.5.2 Extract Attribute Values to Generate Output from a Container (Karma) может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Extract Attribute Values to Generate Output from a Container (Karma) ::
реклама |