diff --git a/alib2std/src/extensions/vector.hpp b/alib2std/src/extensions/vector.hpp index 69164eb3bae6841261cb7940de5d3e65e578b6e3..ac38f9ceea79286b874a0613150394d645af8630 100644 --- a/alib2std/src/extensions/vector.hpp +++ b/alib2std/src/extensions/vector.hpp @@ -133,6 +133,9 @@ inline vectorBoolInternalType getMask ( size_t dist ) { template < class ... Ts > vector < bool, Ts ... > & operator <<= ( vector < bool, Ts ... > & A, size_t dist ) { + if ( A.size ( ) == 0 ) + return A; + size_t distBlocks = dist / vectorBoolInternalTypeInBits; size_t distWithin = dist % vectorBoolInternalTypeInBits; size_t backDist = vectorBoolInternalTypeInBits - distWithin; @@ -151,18 +154,19 @@ vector < bool, Ts ... > & operator <<= ( vector < bool, Ts ... > & A, size_t dis * ( itAReverse._M_p -- ) = 0; } + if ( distWithin == 0 ) + return A; + // shift by the rest dist { vectorBoolInternalType bits1 { }; vectorBoolInternalType bits2 { }; - // reuse bits1 which is zeroed in initialization to create one and the mask - vectorBoolInternalType mask = ~ getMask ( distWithin ); // it might be more clear to iterate from the begining. However this is working nicely auto itA = A.begin ( ); while ( itA < A.end ( ) ) { - bits2 = * ( itA._M_p ) & mask; + bits2 = * ( itA._M_p ); * ( itA._M_p ) = * ( itA._M_p ) << distWithin | bits1 >> backDist; bits1 = bits2; @@ -181,6 +185,9 @@ vector < bool, Ts ... > operator << ( vector < bool, Ts ... > A, size_t dist ) { template < class ... Ts > vector < bool, Ts ... > & operator >>= ( vector < bool, Ts ... > & A, size_t dist ) { + if ( A.size ( ) == 0 ) + return A; + size_t distBlocks = dist / vectorBoolInternalTypeInBits; size_t distWithin = dist % vectorBoolInternalTypeInBits; size_t sizeWithin = A.size ( ) % vectorBoolInternalTypeInBits; @@ -199,12 +206,13 @@ vector < bool, Ts ... > & operator >>= ( vector < bool, Ts ... > & A, size_t dis * ( itA._M_p ++ ) = 0; } + if ( distWithin == 0 ) + return A; + // shift by the rest dist { vectorBoolInternalType bits1 { }; vectorBoolInternalType bits2 { }; - // reuse bits1 which is zeroed in initialization to create one and the mask - vectorBoolInternalType mask = getMask ( distWithin ); // it might be more clear to iterate from the begining. However this is working nicely auto itAReverse = A.end ( ) - 1; @@ -216,7 +224,7 @@ vector < bool, Ts ... > & operator >>= ( vector < bool, Ts ... > & A, size_t dis // simulate behavior of reverse iterator while ( itAReverse >= A.begin ( ) ) { - bits2 = * ( itAReverse._M_p ) & mask; + bits2 = * ( itAReverse._M_p ); * ( itAReverse._M_p ) = * ( itAReverse._M_p ) >> distWithin | bits1 << backDist; bits1 = bits2; diff --git a/alib2std/test-src/extensions/VectorTest.cpp b/alib2std/test-src/extensions/VectorTest.cpp index 19a2a51bc7c6c4f4fcfccb41bb3bd727fa74e8ff..05a3e2396e2b9eb94513817225f1e5f6c6bc55ee 100644 --- a/alib2std/test-src/extensions/VectorTest.cpp +++ b/alib2std/test-src/extensions/VectorTest.cpp @@ -81,11 +81,11 @@ void VectorTest::testVectorBool() { } } -void testOffset ( int offset ) { +void testOffset ( long offset, long shift ) { unsigned long long shadow = 0x2A76B147D6521C87ULL; std::vector < bool > data; - for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8 + offset; ++ i ) { + for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 16 + offset; ++ i ) { data.push_back ( true ); } @@ -93,10 +93,10 @@ void testOffset ( int offset ) { data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) ); } - data >>= sizeof ( unsigned long long ) * 6 - 1; + data >>= sizeof ( unsigned long long ) * 6 + shift; std::vector < bool > ref; - for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 2 + offset; ++ i ) { + for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 10 + offset - shift; ++ i ) { ref.push_back ( true ); } @@ -104,8 +104,10 @@ void testOffset ( int offset ) { ref.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) ); } - ref.resize ( 128 + offset ); + ref.resize ( 192 + offset ); + std::cout << "offset = " << offset << std::endl; + std::cout << "shift = " << shift << std::endl; std::cout << "data = " << data << std::endl; std::cout << "ref = " << ref << std::endl; @@ -128,13 +130,14 @@ void VectorTest::testVectorBool2() { ref.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) ); } - // std::cout << "data = " << data << std::endl; - // std::cout << "ref = " << ref << std::endl; + std::cout << "data = " << data << std::endl; + std::cout << "ref = " << ref << std::endl; CPPUNIT_ASSERT ( data == ref ); - for ( unsigned long i = - sizeof ( unsigned long long ) / 2 ; i < sizeof ( unsigned long long ) * 8; ++ i ) - testOffset ( i ); + for ( long i = - ( long ) sizeof ( unsigned long long ) / 2 ; i < ( long ) sizeof ( unsigned long long ) * 8; ++ i ) + for ( long j = - ( long ) sizeof ( unsigned long long ) / 2 ; j < ( long ) sizeof ( unsigned long long ) * 8; ++ j ) + testOffset ( i, j ); } void VectorTest::testVectorBool3() { @@ -184,7 +187,7 @@ void VectorTest::testVectorBool3() { CPPUNIT_ASSERT ( data2 == data ); } -void testOffset2 ( int offset ) { +void testOffset2 ( long offset, long shift ) { unsigned long long shadow = 0x2A76B147D6521C87ULL; std::vector < bool > data; @@ -196,10 +199,14 @@ void testOffset2 ( int offset ) { data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) ); } - data <<= sizeof ( unsigned long long ) * 2 + 1; + data <<= sizeof ( unsigned long long ) * 2 + shift; std::vector < bool > ref; - for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 10 + offset; ++ i ) { + for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 2 + shift; ++ i ) { + ref.push_back ( false ); + } + + for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8 + offset; ++ i ) { ref.push_back ( true ); } @@ -209,6 +216,8 @@ void testOffset2 ( int offset ) { ref.resize ( 128 + offset ); + std::cout << "offset = " << offset << std::endl; + std::cout << "shift = " << shift << std::endl; std::cout << "data = " << data << std::endl; std::cout << "ref = " << ref << std::endl; @@ -236,8 +245,9 @@ void VectorTest::testVectorBool4() { CPPUNIT_ASSERT ( data == ref ); - for ( unsigned long i = - sizeof ( unsigned long long ) / 2 ; i < sizeof ( unsigned long long ) * 8; ++ i ) - testOffset2 ( i ); + for ( long i = - ( long ) sizeof ( unsigned long long ) / 2 ; i < ( long ) sizeof ( unsigned long long ) * 8; ++ i ) + for ( long j = - ( long ) sizeof ( unsigned long long ) / 2 ; j < ( long ) sizeof ( unsigned long long ) * 8; ++ j ) + testOffset2 ( i, j ); } void VectorTest::testVectorBool5() {