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

Collections comparison

Boost , Boost.Test , Extended comparisons support

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

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

  • Сбор какпоследовательность значений: Например, когда<N>значения хранятся в контейнере. Контейнеры в этом случае используются для хранения нескольких значений, и итерация над контейнерами дает последовательности, которые можно сравнитьс точки зрения элемента.. Итерация должна быть в порядкеa prioriизвестно, поскольку оно способно сравнивать последовательности. Значения в коллекции независимы друг от друга, и подмножества также можно сравнить.
  • Сборник какансамбль: Это тот случай, когда элементы коллекции определяютсущность, и ни один элемент не может быть отделен от других. Примером может служить набор букв для конкретного слова в естественном языке; в этих условиях любой из символов в слове/сборе зависитсемантическиот другого, и невозможно взять его подмножество, не нарушая значения слова. Другим примером может служить вектор размера<N>, представляющий точку в<N>размерном пространстве, по сравнению с другой точкой с отношением «<<>»: сравнение является специфическим для приложения, и возможным сравнением будет лексикографическое упорядочение.

Можно сделать следующие замечания:

  • методы, используемые для сравнения коллекций, должны быть подобраны в соответствии со значением коллекции;
  • Сравнение последовательностейс точки зрения элементовчасто включает в себя написание циклов в испытательном органе, и если специальный инструмент уже находится на месте, испытательный орган получит ясность и выразительность (включая отчет в случае отказа),
  • Некоторые методы сравнения, такие как лексикографический, имеют хорошее общее поведение (например, полное упорядочение, определяемое для коллекций разного размера), но иногда неуместны.

<BOOST_TEST>предоставляет специальные инструменты для сравнения коллекций:

  • нативныйоператор контейнера коллекции, который упоминается какповедение по умолчанию.
  • (61) сравнение с использованием элементов, для которого предусмотрена расширенная диагностика отказов;
  • и с использованиемлексикографическогосравнения, для которого предусмотрена расширенная диагностика отказов,

Подробнее о концепциисборникавЕдиничный испытательный каркасприведенздесь.

Default comparison

Сравнительные сообщения по умолчанию отправляются существующему перегруженному оператору. В двух из них<c_a>и<c_b>.

BOOST_TEST(c_a op c_b)

Это эквивалентно, с точки зрения успеха теста,

auto result = c_a op c_b;
BOOST_TEST(result);

В приведенном ниже примере<operator==>не определен для<std::vector>различных типов, и программа не смогла бы собрать, если бы соответствующие строки были некомментированы<std::vector>использует лексикографическое сравнение по умолчанию.

[Note] Note

При этом дополнительной диагностики не предусмотрено.Единичная система испытаний. См. раздел<BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE>ниже.

Example: BOOST_TEST containers comparison default

Код

<
#defineBOOST_TEST_MODULEboost_test_sequence
#include<boost/test/included/unit_test.hpp>
#include<vector>
BOOST_AUTO_TEST_CASE(test_collections_vectors)
{
 std::vector<int>a{1,2,3},c{1,5,3,4};
 std::vector<long>b{1,5,3};
 // the following does not compile
 //BOOST_TEST(a == b);
 //BOOST_TEST(a <= b);
 // stl defaults to lexicographical comparison
 BOOST_TEST(a<c);
 BOOST_TEST(a>=c);
 BOOST_TEST(a!=c);
}
>

выход

<
>./boost_test_container_default--log_level=all
Running1testcase...
Enteringtestmodule"boost_test_sequence"
test.cpp(13):Enteringtestcase"test_collections_vectors"
test.cpp(23):info:checka<chaspassed
test.cpp(24):error:in"test_collections_vectors":checka>=chasfailed
test.cpp(25):info:checka!=chaspassed
test.cpp(13):Leavingtestcase"test_collections_vectors";testingtime:208us
Leavingtestmodule"boost_test_sequence";testingtime:286us
***1failureisdetectedinthetestmodule"boost_test_container_default"
>

Element-wise comparison

Уточняя манипулятор<boost::test_tools::per_element>, сравнение элементов контейнеров выполняетсяэлемент-мудрый, в порядке, указанном передними итераторами контейнеров. Это сравнение последовательностейэлементов, генерируемых контейнерами, для которыхUnit Test Frameworkобеспечивает расширенную диагностику.

Более подробно, пусть<c_a=(a_1,...a_n)>и<c_b =(b_1,...b_n)>будут двумя последовательностями одинаковой длины, но не обязательно одного и того же типа. Эти последовательности соответствуют содержанию соответствующих контейнеров в порядке, указанном их итератором. Пусть<op>будет одним изоператоров бинарного сравнения.

BOOST_TEST(c_a op c_b, boost::test_tools::per_element() );

является эквивалентным

if(c_a.size() == c_b.size())
{
  for(int i=0; i < c_a.size(); i++)
  {
    BOOST_TEST_CONTEXT("index " << i)
    {
      BOOST_TEST(a_i op b_i);
    }
  }
}
else
{
  BOOST_TEST(c_a.size() == c_b.size());
}
[Warning] Warning

Это принципиально отличается от использования операторов сравнения контейнеров по умолчанию (поведение по умолчанию).

[Warning] Warning

Это не отношения заказа на контейнеры. В качестве побочного эффекта можно

BOOST_TEST(c_a == c_b)

и

BOOST_TEST(c_a != c_b)

Неудачи одновременно

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

Example: BOOST_TEST sequence comparison

Код

<
#defineBOOST_TEST_MODULEboost_test_sequence_per_element
#include<boost/test/included/unit_test.hpp>
#include<vector>
#include<list>
namespacett=boost::test_tools;
BOOST_AUTO_TEST_CASE(test_sequence_per_element)
{
 std::vector<int>a{1,2,3};
 std::vector<long>b{1,5,3};
 std::list<short>c{1,5,3,4};
 BOOST_TEST(a==b,tt::per_element());// nok: a[1] != b[1]
 BOOST_TEST(a!=b,tt::per_element());// nok: a[0] == b[0] ...
 BOOST_TEST(a<=b,tt::per_element());// ok
 BOOST_TEST(b<c,tt::per_element());// nok: size mismatch
 BOOST_TEST(b>=c,tt::per_element());// nok: size mismatch
 BOOST_TEST(b!=c,tt::per_element());// nok: size mismatch
}
>

выход

<
>./boost_test_sequence_per_element
Running1testcase...
test.cpp(21):error:in"test_sequence_per_element":checka==bhasfailed
Mismatchatposition1:2!=5.
test.cpp(23):error:in"test_sequence_per_element":checka!=bhasfailed
Mismatchatposition0:1==1.
Mismatchatposition2:3==3.
test.cpp(25):error:in"test_sequence_per_element":checkb<chasfailed
Collectionssizemismatch:3!=4
test.cpp(26):error:in"test_sequence_per_element":checkb>=chasfailed
Collectionssizemismatch:3!=4
test.cpp(27):error:in"test_sequence_per_element":checkb!=chasfailed
Collectionssizemismatch:3!=4
***5failuresaredetectedinthetestmodule"boost_test_sequence_per_element"
>
Requirements

Для того чтобы последовательности были сопоставимы по элементам, должны выполняться следующие условия:

  • контейнеры должны соответствовать определениюпоследовательности,
  • контейнеры должны содержать одинаковое количество элементов;
  • <op>должен быть одним из операторов сравнения<==>,<!=>,<<>,<<=>,<>>,<>=>
  • <a_iop b_i>должно быть определено, где тип<a_i>и<b_i>являются типом, возвращаемым оператором отсчета соответствующих коллекций.
[Caution] Caution

Полученный тип "<c_a ==c_b>" является<assertion_result>: Невозможно составить более одного сравнения по заявлению<BOOST_TEST>:

BOOST_TEST(c_a == c_b == 42, boost::test_tools::per_element() ); // does not compile

Lexicographic comparison

Указывая манипулятор<boost::test_tools::lexicographic>, контейнеры сравниваются с использованиемлексикографическогопорядка и для которогосравниваются.Блок тестирования Frameworkобеспечивает дополнительную диагностику в случае отказа.

BOOST_TEST(c_a op c_b, boost::test_tools::lexicographic() );

Сравнение выполняется в порядке, указанном передовыми итераторами контейнеров.

[Tip] Tip

Лексикографическое сравнение дает общий порядок на контейнерах: высказывания<c_a< c_b>и<c_b <=c_a>являются взаимоисключающими.

Example: BOOST_TEST container comparison using lexicographical order

Код

<
#defineBOOST_TEST_MODULEboost_test_container_lex
#include<boost/test/included/unit_test.hpp>
#include<vector>
namespacett=boost::test_tools;
BOOST_AUTO_TEST_CASE(test_collections_vectors_lex)
{
 std::vector<int>a{1,2,3},b{1,2,2},c{1,2,3,4};
 BOOST_TEST(a<a,tt::lexicographic());
 BOOST_TEST(a<b,tt::lexicographic());
 BOOST_TEST(a<c,tt::lexicographic());
 BOOST_TEST(a>=c,tt::lexicographic());
 // does not compile
 //BOOST_TEST(a == c, tt::lexicographic());
 //BOOST_TEST(a != c, tt::lexicographic());
}
>

выход

<
>./boost_test_container_lex--log_level=all
Running1testcase...
Enteringtestmodule"boost_test_container_lex"
test.cpp(15):Enteringtestcase"test_collections_vectors_lex"
test.cpp(19):error:in"test_collections_vectors_lex":checka<ahasfailed
Collectionsappeartobeequal.
test.cpp(20):error:in"test_collections_vectors_lex":checka<bhasfailed
Failureatposition2:3>=2.
test.cpp(21):info:checka<chaspassed
test.cpp(22):error:in"test_collections_vectors_lex":checka>=chasfailed
Secondcollectionhasextratrailingelements.
test.cpp(15):Leavingtestcase"test_collections_vectors_lex";testingtime:267us
Leavingtestmodule"boost_test_container_lex";testingtime:341us
***3failuresaredetectedinthetestmodule"boost_test_container_lex"
>
Extended diagnostic by default for specific containers

Как видно выше, лексикографическое сравнение является либо явным (<boost::test_tools::lexicographic()>), либо неявным, когда контейнерные операции используют этот тип сравнения. Во втором случае, однако, невозможно воспользоваться расширенной диагностикой в случае неудачи.

Если лексикографическое сравнение является по умолчанию для конкретного контейнера, можно отправить операции сравнения в.Система испытаний блоковвместо оператора контейнеров. Для того, чтобы избежатьСтруктура модульного тестированиялексикографическое сравнение, макрос<BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE>может использоваться следующим образом:

Example: Default std::vector<int> to lexicographic with extended diagnostic

Код

<
#defineBOOST_TEST_MODULEboost_test_container_lex_default
#include<boost/test/included/unit_test.hpp>
#include<vector>
namespacett=boost::test_tools;
BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE(std::vector<int>)
BOOST_AUTO_TEST_CASE(test_collections_vectors_lex)
{
 std::vector<int>a{1,2,3},b{1,2,2};
 std::vector<longint>c{1,2,3,5},d{1,2,3,4};
 BOOST_TEST(a<a);// extended diagnostic
 BOOST_TEST(a<b);// extended diagnostic
 BOOST_TEST(c<d);// no extended diagnostic
}
>

выход

<
>./boost_test_container_lex_default
Running1testcase...
test.cpp:22:error:in"test_collections_vectors_lex":checka<ahasfailed.
Collectionsappeartobeequal.
test.cpp:23:error:in"test_collections_vectors_lex":checka<bhasfailed.
Failureatposition2:3>=2.
test.run-fail.cpp:24:error:in"test_collections_vectors_lex":checkc<dhasfailed
***3failuresaredetectedinthetestmodule"boost_test_container_lex_default"
>
Requirements
  • контейнеры должны соответствовать определениюпоследовательности,
  • контейнеры должны быть одного и того же типа;
  • <op>должен быть одним из упорядоченных операторов сравнения<<>,<<=>,<>>,<>=>

What is a sequence?

Последовательность дается итерацией надпередним итерируемымконтейнером. Переменный контейнер - это контейнер (C++11):

  • которые реализуют функции<size>и<begin>, а также поля<const_iterator>и<value_type>
  • <value_type>не относится к<char>или<wchar_t>.

С этой точки зрения, C-массивынеявляются передовыми итерируемыми контейнерами:

Example: BOOST_TEST C-arrays

Код

<
#defineBOOST_TEST_MODULEboost_test_container_c
#include<boost/test/included/unit_test.hpp>
#include<sstream>
#include<map>
#include<vector>
BOOST_AUTO_TEST_CASE(test_collections_not_on_c_arrays)
{
 inta[]={1,2,3};
 intb[]={1,5,3,4};
 BOOST_TEST(a==b);
}
>

выход

<
>./boost_test_macro_container_c_array--log_level=all
Running1testcase...
Enteringtestmodule"boost_test_container_c"
test.cpp(15):Enteringtestcase"test_collections_not_on_c_arrays"
test.cpp(19):error:in"test_collections_not_on_c_arrays":checka==bhasfailed[0x7fff526e5bc4!=0x7fff526e5bb0]
test.cpp(15):Leavingtestcase"test_collections_not_on_c_arrays";testingtime:323us
Leavingtestmodule"boost_test_container_c";testingtime:526us
***1failureisdetectedinthetestmodule"boost_test_container_c"
>

Обнаружение контейнеров делегировано классу<boost::unit_test::is_forward_iterable>, который для C++11 обнаруживает необходимые функции и поля участника. Однако для C++03 типы, обеспечивающие последовательности, должны быть явно указаны.Единичная система испытанийпо специализации<boost::unit_test::is_forward_iterable>.



это может быть не так, например,<std::unordered_map>, для которых ведра могут заполняться по-разному в зависимости от порядка вставки.

в данном случае<v_a<v_b>означает, что точка<v_a>находится внутри прямоугольника (происхождение,<v_b>)

определяется контейнером или пользователем

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

Стандартные контейнеры<STL>признаются коллекциями.


PrevUpHomeNext

Статья Collections comparison раздела Boost.Test Extended comparisons support может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Extended comparisons support ::


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 09:56:51/0.011353969573975/0