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

Identifier subtypes

Boost , Chapter 1. The Variadic Macro Data Library 1.9 , Chapter 1. The Variadic Macro Data Library 1.9

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

PrevUpHomeNext

Идентификаторы - это низкоуровневые типы данных, которые макропрограммисты используют для передачи данных предварительной обработки чаще всего. Как мы видели, VMD имеет систему для регистрации и обнаружения идентификаторов, чтобы их можно было анализировать как часть данных препроцессора. Эта система также включает сравнение идентификаторов равенства или неравенства с использованием BOOST_VMD_EQUAL/BOOST_VMD_NOT_EQUAL. и совпадающие идентификаторы с использованием модификаторов идентификаторов в BOOST_VMD_IS_IDENTIFIER и BOOST_VMD_ELEM. Вместе эти средства обеспечивают богатый набор функций для обработки идентификаторов в макросах.

И числа, и v-типы являются подтипами идентификаторов, и оба могут быть индивидуально распознаны как собственные типы данных или работать с идентификаторами с использованием уже упомянутых средств идентификации. Числа, в частности, также имеют богатый набор функций в библиотеке Boost PP. В качестве подтипов числа и v-типы могут использоваться в качестве модификаторов фильтров и могут быть возвращены в качестве конкретных типов либо при вызове модификаторов типа BOOST_VMD_GET_TYPE, либо при использовании модификаторов типа возврата. Кроме того, VMD распознает их отдельные v-типы, BOOST_VMD_TYPE_NUMBER и BOOST_VMD_TYPE_TYPE, как данные VMD при разборе последовательностей.

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

Defining a subtype

Чтобы определить пользовательский подтип, необходимо выполнить несколько шагов. Эти шаги будут подробно разъяснены ниже:

  1. Зарегистрируйте и предварительно определите все идентификаторы этого подтипа.
  2. Зарегистрируйте и предварительно определите имя v-типа для этого подтипа.
  3. Подмножество регистрирует все идентификаторы подтипа.
  4. Подмножество регистрирует имя v-типа для подтипа.

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

Register and pre-detect all identifiers of that subtype

Регистрация и предварительное обнаружение всех идентификаторов этого подтипа точно такие же, как регистрация и предварительное обнаружение любого идентификатора.

Давайте создадим некоторые идентификаторы, основанные на использовании в мифической библиотеке «udef». Мы поместим все наши макросы в файл заголовка udef_vmd_macros.hpp.

Для идентификаторов в нашей библиотеке нам понадобятся разные имена, поэтому мы добавим UDEF_ к именам наших идентификаторов, чтобы сделать их уникальными. Наша библиотека udef имеет геометрические формы, поэтому мы создадим пользовательский подтип, который состоит из идентификаторов для различных форм, которыми наша библиотека udef может манипулировать в своих макросах. Таким образом, наши регистрации идентификаторов и предварительные обнаружения, размещенные в нашем файле заголовка, будут:

#define BOOST_VMD_REGISTER_UDEF_CIRCLE (UDEF_CIRCLE)
#define BOOST_VMD_REGISTER_UDEF_SQUARE (UDEF_SQUARE)
#define BOOST_VMD_REGISTER_UDEF_TRIANGLE (UDEF_TRIANGLE)
#define BOOST_VMD_REGISTER_UDEF_HEXAGON (UDEF_HEXAGON)
#define BOOST_VMD_DETECT_UDEF_CIRCLE_UDEF_CIRCLE
#define BOOST_VMD_DETECT_UDEF_SQUARE_UDEF_SQUARE
#define BOOST_VMD_DETECT_UDEF_TRIANGLE_UDEF_TRIANGLE
#define BOOST_VMD_DETECT_UDEF_HEXAGON_UDEF_HEXAGON

Register and pre-detect a v-type name for that subtype

Нам нужно создать уникальное имя v-типа для нашего пользовательского подтипа. Название не должно начинаться с BOOST_VMD_TYPE_, но оно должно быть уникальным. С тех пор BOOST_VMD_TYPE_ является общим началом всех типов v, которые мы будем использовать для согласованности, но приложим к нему UDEF_ Позволяет придать ему уникальность, которая не должна дублироваться:

#define BOOST_VMD_REGISTER_BOOST_VMD_TYPE_UDEF_SHAPES (BOOST_VMD_TYPE_UDEF_SHAPES)
#define BOOST_VMD_DETECT_BOOST_VMD_TYPE_UDEF_SHAPES_BOOST_VMD_TYPE_UDEF_SHAPES

Subtype register all identifiers of the subtype

Макрос для регистрации подмножества идентификатора начинается с BOOST_VMD_SUBTYPE_REGISTER_, и вы добавляете к нему каждый идентификатор в подмножестве. Это очень похоже на макрос BOOST_VMD_REGISTER_. Разница в том, что в отличие от макроса BOOST_VMD_REGISTER_, который расширяется до кортежа, единственным элементом которого является идентификатор, BOOST_VMD_SUBTYPE_REGISTER_ расширяется до кортежа из двух элементов, где первый элемент является подтипом v-типа, а второй элемент - идентификатором.

Для нашего пользовательского подтипа udef это будет:

#define BOOST_VMD_SUBTYPE_REGISTER_UDEF_CIRCLE (BOOST_VMD_TYPE_UDEF_SHAPES,UDEF_CIRCLE)
#define BOOST_VMD_SUBTYPE_REGISTER_UDEF_SQUARE (BOOST_VMD_TYPE_UDEF_SHAPES,UDEF_SQUARE)
#define BOOST_VMD_SUBTYPE_REGISTER_UDEF_TRIANGLE (BOOST_VMD_TYPE_UDEF_SHAPES,UDEF_TRIANGLE)
#define BOOST_VMD_SUBTYPE_REGISTER_UDEF_HEXAGON (BOOST_VMD_TYPE_UDEF_SHAPES,UDEF_HEXAGON)

Subtype register the v-type name for the subtype

Выполнение регистра подмножества фактического типа udef v довольно легко, как только мы поймем, как зарегистрировать подмножество идентификатора. Единственное, что нужно понять, это то, что тип любого v-типа - это v-тип BOOST_VMD_TYPE_TYPE. Итак, наш подмножественный регистр нашего нового типа v BOOST_VMD_TYPE_UDEF_SHAPES Это:

#define BOOST_VMD_SUBTYPE_REGISTER_BOOST_VMD_TYPE_UDEF_SHAPES (BOOST_VMD_TYPE_TYPE,BOOST_VMD_TYPE_UDEF_SHAPES)

Using our identifier subset

После того, как мы добавили все вышеупомянутые объектоподобные макросы для определения нашего пользовательского подтипа в файл заголовка udef_vmd_macros.hpp, у нас есть новый тип данных, который мы можем использовать в общем, как мы можем использовать числа или v-типы в общем. Важно включать заголовок udef_vmd_macros.hpp в какой-либо блок перевода, когда нам нужна функциональность VMD для нашего нового типа данных. Поэтому в наших примерах мы предположим, что каждому примеру предшествует «#include udef_vmd_macros.hpp».

#include <boost/vmd/get_type.hpp>
#define A_SEQUENCE UDEF_SQUARE
#define A_SEQUENCE2 217
#define A_SEQUENCE3 BOOST_VMD_TYPE_UDEF_SHAPES
#define A_SEQUENCE4 BOOST_VMD_TYPE_NUMBER
BOOST_VMD_GET_TYPE(A_SEQUENCE) will return 'BOOST_VMD_TYPE_UDEF_SHAPES'
BOOST_VMD_GET_TYPE(A_SEQUENCE2) will return 'BOOST_VMD_TYPE_NUMBER'
BOOST_VMD_GET_TYPE(A_SEQUENCE3) will return 'BOOST_VMD_TYPE_TYPE'
BOOST_VMD_GET_TYPE(A_SEQUENCE4) will return 'BOOST_VMD_TYPE_TYPE'

Здесь мы видим, что при использовании макроса BOOST_VMD_GET_TYPE на одноэлементной последовательности, которая является одним из наших определяемых пользователем значений подтипа, мы правильно получаем v-тип нашего определяемого пользователем подтипа, так же, как мы делаем, когда мы запрашиваем тип числа. Кроме того, когда мы используем макрос BOOST_VMD_GET_TYPE на самом v-типе нашего пользовательского подтипа, мы правильно получаем тип всех v-типов, который является BOOST_VMD_TYPE_TYPE, так же, как мы делаем, когда мы запрашиваем тип v-типа числа.

#include <boost/vmd/elem.hpp>
#define A_SEQUENCE5 (1,2) UDEF_TRIANGLE
BOOST_VMD_ELEM(1,A_SEQUENCE5,BOOST_VMD_RETURN_TYPE) will return '(BOOST_VMD_TYPE_UDEF_SHAPES,UDEF_TRIANGLE)'
BOOST_VMD_ELEM(0,A_SEQUENCE5,BOOST_VMD_RETURN_TYPE) will return '(BOOST_VMD_TYPE_TUPLE,(1,2))'

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

#include <boost/vmd/equal.hpp>
#define A_SEQUENCE6 UDEF_CIRCLE
#define A_SEQUENCE7 168
BOOST_VMD_EQUAL(A_SEQUENCE6,UDEF_CIRCLE,BOOST_VMD_TYPE_UDEF_SHAPES) will return '1'
BOOST_VMD_EQUAL(A_SEQUENCE6,UDEF_CIRCLE,BOOST_VMD_TYPE_LIST) will return '0'
BOOST_VMD_EQUAL(A_SEQUENCE7,168,BOOST_VMD_TYPE_NUMBER) will return '1'
BOOST_VMD_EQUAL(A_SEQUENCE7,168,BOOST_VMD_TYPE_SEQ) will return '0'

Здесь мы можем видеть, что мы можем использовать модификатор фильтра с V-типом нашего пользовательского подтипа так же, как мы можем сделать с любым другим V-типом, таким как число V-тип.

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

Uniqueness of identifier subtype values and v-type

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

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

Но с подтипами идентификаторов, когда мы используем макрос BOOST_VMD_SUBTYPE_REGISTER_, чтобы связать V-тип нашего подтипа с нашими идентификаторами подтипа, у нас будут проблемы, если кто-то другой также определил подтип идентификатора, используя те же идентификаторы, что и мы, поскольку мы будем переопределять одно и то же объектоподобное макроимя с другим расширением. Даже если кто-то еще зарегистрировал / предварительно обнаружил идентификатор, который мы используем для подтипа, не определив подтип на основе этого идентификатора, мы будем вызывать проблему, определяющую наш подтип, потому что макросы VMD, которые в общем возвращают тип последовательности или элемента последовательности, возвращают наш подтип в качестве типа, а не просто BOOST_VMD_TYPE_IDENTIFIER, который может ожидать какой-то программист.

Суть в том, что если мы определим пользовательский подтип, его идентификаторы должны быть уникальными в данном блоке перевода, и все же уникальные имена затрудняют для конечного пользователя более естественное использование макросов. В нашем примере с мифической библиотекой udef мы использовали идентификаторы, такие как «UDEF_CIRCLE» и т.д. Таким образом, с пользовательскими подтипами идентификаторов у нас есть компромисс; нам нужны уникальные имена идентификаторов как для наших идентификаторов подтипов, так и для наших идентификаторов подтипов, чтобы не конфликтовать с другими, которые могут использовать подтипы идентификаторов, но эти уникальные имена могут сделать использование макросов менее «естественным». С другой стороны, просто регистрация / предварительное обнаружение идентификаторов не имеет такой проблемы. Это проблема, о которой должен знать любой пользователь, желающий создать свой собственный тип данных с использованием VMD путем определения пользовательских подтипов.


PrevUpHomeNext

Статья Identifier subtypes раздела Chapter 1. The Variadic Macro Data Library 1.9 Chapter 1. The Variadic Macro Data Library 1.9 может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Chapter 1. The Variadic Macro Data Library 1.9 ::


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 18:51:35/0.011217832565308/1