#include <catch2/catch.hpp> #include <common/SparseBoolVector.hpp> #include <common/xml/SparseBoolVector.hpp> #include <factory/XmlDataFactory.hpp> static ext::vector < bool > createTestVectorBool ( size_t size ) { unsigned long long shadow = 0x2A76B147D6521C87ULL; ext::vector < bool > ref; while ( ref.size ( ) < size ) { for ( size_t i = 0; i < sizeof ( unsigned long long ) * 8; ++i ) { ref.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) ); } for ( size_t i = 0; i < 100; ++i ) { ref.push_back ( false ); } } ref.resize ( size ); return ref; } static void testOffset2 ( size_t size, size_t shift ) { ext::vector < bool > ref = createTestVectorBool ( size ); common::SparseBoolVector data = ref; data <<= shift; ref <<= shift; /* std::cout << "size = " << size << std::endl; std::cout << "shift = " << shift << std::endl; std::cout << "data = " << data.data ( ) << std::endl; std::cout << "ref = " << common::SparseBoolVector ( ref ).data ( ) << std::endl;*/ CHECK ( data == common::SparseBoolVector ( ref ) ); } void testIterator ( size_t size ) { ext::vector < bool > ref = createTestVectorBool ( size ); common::SparseBoolVector data ( ref ); size_t count = 0; for ( bool boolean : ref ) { count += boolean; } for ( size_t onePosition : data ) { --count; CHECK ( ref [ onePosition ] ); } CHECK ( count == 0 ); } TEST_CASE ( "Sparse Bool Vector", "[unit][data][string]" ) { SECTION ( "Compatibility with Vector" ) { ext::vector < bool > orig; for ( int i = 0; i < 1000; ++i ) { orig.push_back ( false ); } for ( int i = 0; i < 20; ++i ) { orig.push_back ( true ); orig.push_back ( true ); orig.push_back ( false ); orig.push_back ( true ); orig.push_back ( true ); orig.push_back ( false ); orig.push_back ( true ); orig.push_back ( false ); orig.push_back ( false ); orig.push_back ( true ); } for ( int i = 0; i < 1000; ++i ) { orig.push_back ( false ); } orig.push_back ( true ); orig.push_back ( true ); orig.push_back ( false ); orig.push_back ( true ); orig.push_back ( true ); orig.push_back ( false ); orig.push_back ( true ); orig.push_back ( false ); orig.push_back ( false ); orig.push_back ( true ); common::SparseBoolVector compressed ( orig ); ext::vector < bool > copy ( compressed ); /* std::cout << orig << std::endl; std::cout << copy << std::endl; std::cout << compressed.data ( ) << std::endl;*/ CHECK ( orig == copy ); } SECTION ( "Shifts 4" ) { for ( size_t shift = 0 ; shift < 100; ++ shift ) { testOffset2 ( 0, shift ); testOffset2 ( 31, shift ); testOffset2 ( 32, shift ); testOffset2 ( 33, shift ); testOffset2 ( 63, shift ); testOffset2 ( 64, shift ); testOffset2 ( 65, shift ); testOffset2 ( 1023, shift ); testOffset2 ( 1024, shift ); testOffset2 ( 1025, shift ); testOffset2 ( 2000, shift ); } } SECTION ( "Shifts 5" ) { unsigned long long shadow = 0x2A76B147D6521C87ULL; common::SparseBoolVector data; for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) { data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) ); } for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) { data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) ); } for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) { data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) ); } common::SparseBoolVector data2 = data; data2 <<= 64; data <<= 32; data <<= 16; data <<= 8; data <<= 4; data <<= 2; data <<= 1; data <<= 1; /* std::cout << "data = " << data.data ( ) << std::endl; std::cout << "data2 = " << data2.data ( ) << std::endl;*/ data2 <<= 1; data2 <<= 2; data2 <<= 4; data2 <<= 8; data2 <<= 16; data2 <<= 32; data2 <<= 1; data <<= 27; data <<= 17; data <<= 13; data <<= 7; /* std::cout << "data = " << data.data ( ) << std::endl; std::cout << "data2 = " << data2.data ( ) << std::endl;*/ CHECK ( data2 == data ); } SECTION ( "Ones Iterator" ) { for ( size_t i = 0; i < 1000; i++ ) { testIterator ( i ); } common::SparseBoolVector empty; CHECK ( empty.begin ( ) == empty.end ( ) ); empty.push_back ( false ); CHECK ( empty.begin ( ) == empty.end ( ) ); } SECTION ( "Compare" ) { common::SparseBoolVector first; common::SparseBoolVector second; common::SparseBoolVector third; common::SparseBoolVector fourth; common::SparseBoolVector fifth; common::SparseBoolVector sixth; first.push_back ( false ); second.push_back ( true ); third.push_back ( false ); third.push_back ( false ); fourth.push_back ( true ); fourth.push_back ( false ); fifth.push_back ( false ); fifth.push_back ( true ); sixth.push_back ( true ); sixth.push_back ( true ); CHECK ( first == first ); CHECK ( first < second ); CHECK ( second > first ); CHECK ( second == second ); CHECK ( third == third ); CHECK ( third < fourth ); CHECK ( third < fifth ); CHECK ( third < sixth ); CHECK ( fourth > third ); CHECK ( fourth == fourth ); CHECK ( fourth < fifth ); CHECK ( fourth < sixth ); CHECK ( fifth > third ); CHECK ( fifth > fourth ); CHECK ( fifth == fifth ); CHECK ( fifth < sixth ); CHECK ( sixth > third ); CHECK ( sixth > fourth ); CHECK ( sixth > fifth ); CHECK ( sixth == sixth ); } SECTION ( "Array Subscript" ) { { ext::vector < bool > ref = createTestVectorBool ( 2000 ); common::SparseBoolVector data ( ref ); /* std::cout << ref << std::endl; std::cout << data.data ( ) << std::endl;*/ for ( size_t i = 0; i < ref.size ( ); ++ i ) { INFO ( "Failed on index " << i ); CHECK ( ( bool ) ref [ i ] == ( bool ) data [ i ] ); } } { ext::vector < bool > ref; common::SparseBoolVector data; ref.resize ( 2000 ); data.resize ( 2000 ); ref[520] = true; data[520] = true; CHECK ( ( ext::vector < bool > ) data == ref ); ref[521] = true; data[521] = true; CHECK ( ( ext::vector < bool > ) data == ref ); ref[128] = true; data[128] = true; CHECK ( ( ext::vector < bool > ) data == ref ); ref[255] = true; data[255] = true; CHECK ( ( ext::vector < bool > ) data == ref ); ref[256] = true; data[256] = true; CHECK ( ( ext::vector < bool > ) data == ref ); } SECTION ( "Overloaded bitwise and" ) { ext::vector < bool > first; ext::vector < bool > second; ext::vector < bool > ref; first.resize ( 2000 ); second.resize ( 2000 ); ref.resize ( 2000 ); first[520] = first[1] = first[3] = first[512] = first[511] = first[128] = first[127] = first[17] = first[53] = first[1999] = true; second[80] = second[1] = second[5] = second[51] = second[5] = second[7] = second[127] = second[1] = second[77] = second[999] = true; ref[1] = ref[127] = true; common::SparseBoolVector data; CHECK ( ( first & second ) == ref ); } SECTION ( "Xml Api" ) { ext::vector < bool > ref = createTestVectorBool ( 2000 ); common::SparseBoolVector data ( ref ); ext::deque<sax::Token> tokens = factory::XmlDataFactory::toTokens( data ); std::string tmp = sax::SaxComposeInterface::composeMemory ( tokens ); // std::cout << tmp << std::endl; ext::deque<sax::Token> tokens2 = sax::SaxParseInterface::parseMemory ( tmp ); common::SparseBoolVector data2 = factory::XmlDataFactory::fromTokens ( std::move ( tokens2 ) ); /* std::cout << data.data ( ) << std::endl; std::cout << data2.data ( ) << std::endl;*/ CHECK( data == data2 ); } } }