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

Testing for equality and inequality

Boost , Chapter 1. The Variadic Macro Data Library 1.9 , Generic macros for working with data types

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 позволяет программисту тестировать равенство или неравенство любого значения, которое VMD может разобрать. Это включает в себя пустоту, идентификаторы, числа, типы, массивы, списки, секвы, кортежи и многоэлементные последовательности.

Макро для проверки на равенство называется BOOST_VMD_EQUAL и имеет два необходимых параметра, которые являются двумя значениями для проверки. Значения могут быть любого типа данных VMD.

Для композитных типов данных массива, списка, seq и tuple или любого из этих типов в многоэлементной последовательности элементы этих типов также должны быть типом данных, который VMD может анализировать. BOOST_VMD_EQUAL Рекурсивно анализирует элементы в композитном типе данных для равенства до уровня 16 внутренних типов, чтобы проверить, что один композитный тип равен другому композитному типу. Требование о том, что композитные элементы также должны быть типом данных, который VMD может анализировать, отличается от большинства других макросов в библиотеке VMD, где для определения типа данных необходимо анализировать только композитный тип верхнего уровня. Если BOOST_VMD_EQUAL сталкивается с типом данных, который он не может разобрать, результатом будет UB.

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

BOOST_VMD_EQUAL макрос возвращает 1, если оба параметра равны, и 0, если параметры не равны.

И наоборот, для проверки на неравенство тех же значений, которые необходимы при тестировании на равенство, библиотека VMD имеет макрос. BOOST_VMD_NOT_EQUAL. Этот макрос является дополнением макроса BOOST_VMD_EQUAL. Если BOOST_VMD_EQUAL возвращается 1 то BOOST_VMD_NOT_EQUAL Если BOOST_VMD_EQUAL возвращается 0, то BOOST_VMD_NOT_EQUAL Возвращение 1.

Макросы BOOST_VMD_EQUAL и BOOST_VMD_NOT_EQUAL называются макросами равенства.

#include <boost/vmd/equal.hpp>
#define BOOST_VMD_REGISTER_AN_ID1 (AN_ID1)
#define BOOST_VMD_REGISTER_AN_ID2 (AN_ID2)
#define BOOST_VMD_DETECT_AN_ID1_AN_ID1
#define BOOST_VMD_DETECT_AN_ID2_AN_ID2
#define AN_IDENTIFIER1 AN_ID1
#define AN_IDENTIFIER2 AN_ID2
#define AN_IDENTIFIER3 AN_ID1 // same as AN_IDENTIFIER1 = AN_ID1
#define A_NUMBER1 33
#define A_NUMBER2 145
#define A_NUMBER3 33 // same as A_NUMBER1 = 33
#define A_TUPLE1 (AN_IDENTIFIER1,A_NUMBER1)
#define A_TUPLE2 (AN_IDENTIFIER1,A_NUMBER2)
#define A_TUPLE3 (AN_IDENTIFIER3,A_NUMBER3) // same as A_TUPLE1 = (AN_ID1,33)
#define A_SEQ1 (A_NUMBER1)(A_TUPLE1)
#define A_SEQ2 (A_NUMBER2)(A_TUPLE2)
#define A_SEQ3 (A_NUMBER3)(A_TUPLE3) // same as A_SEQ1 = (33)((AN_ID1,33))
BOOST_VMD_EQUAL(AN_IDENTIFIER1,AN_IDENTIFIER2) will return 0
BOOST_VMD_EQUAL(AN_IDENTIFIER1,AN_IDENTIFIER3) will return 1
BOOST_VMD_EQUAL(A_NUMBER1,A_NUMBER2) will return 0
BOOST_VMD_EQUAL(A_NUMBER1,A_NUMBER3) will return 1
BOOST_VMD_EQUAL(A_TUPLE1,A_TUPLE2) will return 0
BOOST_VMD_EQUAL(A_TUPLE1,A_TUPLE3) will return 1
BOOST_VMD_EQUAL(A_SEQ1,A_SEQ2) will return 0
BOOST_VMD_EQUAL(A_SEQ1,A_SEQ3) will return 1

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

#define TUPLE_IS_ARRAY1 (2,(3,4))
#define TUPLE_IS_ARRAY2 (2,(4,5))
#define TUPLE_IS_ARRAY3 (2,(3,4))
#define TUPLE_IS_LIST1 (55,BOOST_PP_NIL)
#define TUPLE_IS_LIST2 (135,BOOST_PP_NIL)
#define TUPLE_IS_LIST3 (55,BOOST_PP_NIL)
#define TUPLE_IS_LIST_OR_ARRAY1 (2,(3,BOOST_PP_NIL))
#define TUPLE_IS_LIST_OR_ARRAY2 (2,(4,BOOST_PP_NIL))
#define TUPLE_IS_LIST_OR_ARRAY3 (2,(3,BOOST_PP_NIL))
#define TUPLE_BUT_INVALID_ARRAY1 (&2,(3,4))
#define TUPLE_BUT_INVALID_ARRAY2 (&2,(4,4))
#define TUPLE_BUT_INVALID_ARRAY3 (&2,(3,4))
#define TUPLE_BUT_INVALID_LIST1 (55,^BOOST_PP_NIL)
#define TUPLE_BUT_INVALID_LIST2 (135,^BOOST_PP_NIL)
#define TUPLE_BUT_INVALID_LIST3 (55,^BOOST_PP_NIL)

Все конструкции выше являются действительными кортежами.

Первые три являются действительными массивами, поэтому они будут разобраны и сопоставлены с массивами, чтобы их можно было использовать как:

#include <boost/vmd/equal.hpp>
BOOST_VMD_EQUAL(TUPLE_IS_ARRAY1,TUPLE_IS_ARRAY2) will return 0
BOOST_VMD_EQUAL(TUPLE_IS_ARRAY1,TUPLE_IS_ARRAY3) will return 1

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

#include <boost/vmd/equal.hpp>
BOOST_VMD_EQUAL(TUPLE_IS_LIST1,TUPLE_IS_LIST2) will return 0
BOOST_VMD_EQUAL(TUPLE_IS_LIST1,TUPLE_IS_LIST3) will return 1

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

#include <boost/vmd/equal.hpp>
BOOST_VMD_EQUAL(TUPLE_IS_LIST_OR_ARRAY1,TUPLE_IS_LIST_OR_ARRAY2) will return 0
BOOST_VMD_EQUAL(TUPLE_IS_LIST_OR_ARRAY1,TUPLE_IS_LIST_OR_ARRAY3) will return 1

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

#include <boost/vmd/equal.hpp>
BOOST_VMD_EQUAL(TUPLE_BUT_INVALID_ARRAY1,TUPLE_BUT_INVALID_ARRAY1) will generate UB
BOOST_VMD_EQUAL(TUPLE_BUT_INVALID_ARRAY1,TUPLE_BUT_INVALID_ARRAY1) will generate UB

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

#include <boost/vmd/equal.hpp>
BOOST_VMD_EQUAL(TUPLE_BUT_INVALID_LIST1,TUPLE_BUT_INVALID_LIST2) will generate UB
BOOST_VMD_EQUAL(TUPLE_BUT_INVALID_LIST1,TUPLE_BUT_INVALID_LIST3) will generate UB

Возможно, что композитный тип данных, который имеет элемент, который VMD не может разобрать, не даст UB при сравнении для равенства, а скорее просто тест на равенство потерпит неудачу. Это может произойти, если алгоритм, который тестирует на равенство, неверен перед разбором конкретного элемента. Такая ситуация может быть:

#include <boost/vmd/equal.hpp>
#define A_TUPLE1 (3,4,"astring")
#define A_TUPLE2 (3,4)
BOOST_VMD_EQUAL(A_TUPLE1,A_TUPLE2) will return 0 rather than generate UB

Причина, по которой вышеприведенное корректно возвращает 0, а не генерирует UB, когда VMD пытается разобрать «astring», который не является типом данных, который может разобрать VMD, заключается в том, что алгоритм тестирования тестов равенства имеет ли кортежи одинаковое количество элементов, прежде чем он проверит равенство каждого элемента. Это всего лишь один пример, когда тестирование на равенство может провалиться до того, как UB будет сформирован, когда BOOST_VMD_EQUAL попытается разобрать тип данных, с которым он не может справиться. Тем не менее, общее правило по-прежнему следует считать, что для BOOST_VMD_EQUAL/BOOT_VMD_NOT_EQUAL Все типы данных, даже элемент композитного типа данных, должен быть типом данных VMD, если макрос должен работать должным образом.

Usage

Вы можете использовать общий файл заголовка:

#include <boost/vmd/vmd.hpp>

Или вы можете использовать отдельные файлы заголовка:

#include <boost/vmd/equal.hpp> for the BOOST_VMD_EQUAL macro
#include <boost/vmd/not_equal.hpp> for the BOOST_VMD_NOT_EQUAL macro

PrevUpHomeNext

Статья Testing for equality and inequality раздела Chapter 1. The Variadic Macro Data Library 1.9 Generic macros for working with data types может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Generic macros for working with data types ::


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 06:35:27/0.0094840526580811/1