From 084e5fed5c458b80fa25c226a25bc625c29e2873 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 27 Apr 2018 15:42:32 +0200 Subject: [PATCH] revert to bit by bit vector bool extra operation --- alib2std/src/extensions/vector.hpp | 172 +++++++++++++++----- alib2std/test-src/extensions/VectorTest.cpp | 18 ++ alib2std/test-src/extensions/VectorTest.h | 2 + 3 files changed, 153 insertions(+), 39 deletions(-) diff --git a/alib2std/src/extensions/vector.hpp b/alib2std/src/extensions/vector.hpp index b9e0c8695f..4b9ff7207c 100644 --- a/alib2std/src/extensions/vector.hpp +++ b/alib2std/src/extensions/vector.hpp @@ -16,6 +16,8 @@ #include "compare.hpp" #include "allocFix.hpp" +#include <iostream> + namespace ext { template < class T, class Alloc = std::allocator < T > > @@ -79,18 +81,45 @@ std::string to_string ( const ext::vector < T, Ts ... > & value ) { return ss.str(); } +/*// the same type as the ext::vector bool's internal storage type +typedef typename std::decay < decltype ( * ( std::declval < ext::vector < bool > > ( ).begin ( )._M_p ) ) >::type vectorBoolInternalType; +// the size of the ext::vector bool's internal storage type +const unsigned vectorBoolInternalTypeInBits = sizeof ( vectorBoolInternalType ) * 8; + +// private helper for mask computation +inline vectorBoolInternalType getMask ( size_t dist ) { + if ( dist == 0 ) + return ~ vectorBoolInternalType { }; + else + return ( ( vectorBoolInternalType { } + 1 ) << dist ) - 1; +}*/ + template < class ... Ts > ext::vector < bool, Ts ... > & operator |= ( ext::vector < bool, Ts ... > & A, const ext::vector < bool, Ts ... > & B ) { - A.resize ( std::max ( A.size ( ), B.size ( ) ) ); + // c++ implementation-specific + /* A.resize ( std::max ( A.size ( ), B.size ( ) ), false ); typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( ); typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( ); - // c++ implementation-specific - while ( itB < B.end ( ) ) // A is longer or of the same size as B + while ( itB + 1 < B.end ( ) ) // A is longer or of the same size as B * ( itA._M_p ++ ) |= * ( itB._M_p ++ ); // word-at-a-time bitwise operation - // The rest of A above the size of B can be left intact + size_t sizeWithin = B.size ( ) % vectorBoolInternalTypeInBits; + + if ( itB < B.end ( ) ) { + * ( itA._M_p ++ ) |= * ( itB._M_p ++ ) & getMask ( sizeWithin ); + } + + // The rest of A above the size of B can be left intact */ + + A.resize ( std::max ( A.size ( ), B.size ( ) ), false ); + + typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( ); + typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( ); + + for ( ; itB < B.end ( ); ++ itB, ++ itA ) + * itA = * itA | * itB; return A; } @@ -103,17 +132,35 @@ ext::vector < bool, Ts ... > operator | ( ext::vector < bool, Ts ... > A, const template < class ... Ts > ext::vector < bool, Ts ... > & operator &= ( ext::vector < bool, Ts ... > & A, const ext::vector < bool, Ts ... > & B ) { - A.resize ( std::max ( A.size ( ), B.size ( ) ) ); + // c++ implementation-specific + /* A.resize ( std::max ( A.size ( ), B.size ( ) ), false ); typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( ); typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( ); - // c++ implementation-specific - while ( itB < B.end ( ) ) // A is longer or of the same size as B + while ( itB + 1 < B.end ( ) ) { // A is longer or of the same size as B * ( itA._M_p ++ ) &= * ( itB._M_p ++ ); // word-at-a-time bitwise operation + } + + size_t sizeWithin = B.size ( ) % vectorBoolInternalTypeInBits; + + if ( itB < B.end ( ) ) { + * ( itA._M_p ++ ) &= * ( itB._M_p ++ ) & getMask ( sizeWithin ); + } - while ( itA < A.end ( ) ) // The rest of A above the size of B shall be zeroed + while ( itA < A.end ( ) ) { // The rest of A above the size of B shall be zeroed * ( itA._M_p ++ ) = 0; + }*/ + + // c++ compilant + typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( ); + typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( ); + + for ( ; itB < B.end ( ) && itA < A.end ( ); ++ itB, ++ itA ) + * itA = * itA & * itB; + + for ( ; itA < A.end ( ); ++ itA ) + * itA = false; return A; } @@ -126,19 +173,34 @@ ext::vector < bool, Ts ... > operator & ( ext::vector < bool, Ts ... > A, const template < class ... Ts > ext::vector < bool, Ts ... > & operator ^= ( ext::vector < bool, Ts ... > & A, const ext::vector < bool, Ts ... > & B ) { - A.resize ( std::max ( A.size ( ), B.size ( ) ) ); + // c++ implementation-specific + /* A.resize ( std::max ( A.size ( ), B.size ( ) ), false ); typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( ); typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( ); - // c++ implementation-specific - while ( itB < B.end ( ) ) // A is longer or of the same size as B + while ( itB + 1 < B.end ( ) ) // A is longer or of the same size as B * ( itA._M_p ++ ) ^= * ( itB._M_p ++ ); // word-at-a-time bitwise operation + size_t sizeWithin = B.size ( ) % vectorBoolInternalTypeInBits; + + if ( itB < B.end ( ) ) { + * ( itA._M_p ++ ) ^= * ( itB._M_p ++ ) & getMask ( sizeWithin ); + } + while ( itA < A.end ( ) ) { // The rest of A above the size of B shall be flipped * ( itA._M_p ) = ~ * ( itA._M_p ); itA._M_p ++; - } + }*/ + + // c++ compilant + A.resize ( std::max ( A.size ( ), B.size ( ) ), false ); + + typename ext::vector < bool, Ts ... >::iterator itA = A.begin ( ); + typename ext::vector < bool, Ts ... >::const_iterator itB = B.begin ( ); + + for ( ; itB < B.end ( ); ++ itB, ++ itA ) + * itA = * itA ^ * itB; return A; } @@ -155,19 +217,9 @@ ext::vector < bool, Ts ... > operator ~ ( ext::vector < bool, Ts ... > A ) { return A; } -// the same type as the ext::vector bool's internal storage type -typedef typename std::decay < decltype ( * ( std::declval < ext::vector < bool > > ( ).begin ( )._M_p ) ) >::type vectorBoolInternalType; -// the size of the ext::vector bool's internal storage type -const unsigned vectorBoolInternalTypeInBits = sizeof ( vectorBoolInternalType ) * 8; - -// private helper for mask computation -inline vectorBoolInternalType getMask ( size_t dist ) { - return ( ( vectorBoolInternalType { } + 1 ) << dist ) - 1; -} - template < class ... Ts > ext::vector < bool, Ts ... > & operator <<= ( ext::vector < bool, Ts ... > & A, size_t dist ) { - if ( A.size ( ) == 0 ) +/* if ( A.size ( ) == 0 ) return A; size_t distBlocks = dist / vectorBoolInternalTypeInBits; @@ -204,6 +256,20 @@ ext::vector < bool, Ts ... > & operator <<= ( ext::vector < bool, Ts ... > & A, bits1 = bits2; itA._M_p ++; + }*/ + + // c++ compilant + if ( dist > A.size ( ) ) { + clear ( A ); + } else { + typename ext::vector < bool, Ts ... >::reverse_iterator itASource = A.rbegin ( ) + dist; + typename ext::vector < bool, Ts ... >::reverse_iterator itADest = A.rbegin ( ); + + for ( ; itASource < A.rend ( ); ++ itASource, ++ itADest ) + * itADest = * itASource; + + for ( ; itADest < A.rend ( ); ++ itADest ) + * itADest = false; } return A; @@ -217,7 +283,7 @@ ext::vector < bool, Ts ... > operator << ( ext::vector < bool, Ts ... > A, size_ template < class ... Ts > ext::vector < bool, Ts ... > & operator >>= ( ext::vector < bool, Ts ... > & A, size_t dist ) { - if ( A.size ( ) == 0 ) + /*if ( A.size ( ) == 0 ) return A; size_t distBlocks = dist / vectorBoolInternalTypeInBits; @@ -226,8 +292,7 @@ ext::vector < bool, Ts ... > & operator >>= ( ext::vector < bool, Ts ... > & A, size_t backDist = vectorBoolInternalTypeInBits - distWithin; // upper part of the last word in the ext::vector can contain some garbage so it needs to be cleared - if ( sizeWithin != 0 ) - * ( ( A.end ( ) - 1 )._M_p ) &= getMask ( sizeWithin ); + * ( ( A.end ( ) - 1 )._M_p ) &= getMask ( sizeWithin ); // shift blocks if needed if ( distBlocks ) { @@ -259,6 +324,20 @@ ext::vector < bool, Ts ... > & operator >>= ( ext::vector < bool, Ts ... > & A, bits1 = bits2; itAReverse._M_p --; + }*/ + + // c++ compilant + if ( dist > A.size ( ) ) { + clear ( A ); + } else { + typename ext::vector < bool, Ts ... >::iterator itASource = A.begin ( ) + dist; + typename ext::vector < bool, Ts ... >::iterator itADest = A.begin ( ); + + for ( ; itASource < A.end ( ); ++ itASource, ++ itADest ) + * itADest = * itASource; + + for ( ; itADest < A.end ( ); ++ itADest ) + * itADest = false; } return A; @@ -272,37 +351,52 @@ ext::vector < bool, Ts ... > operator >> ( ext::vector < bool, Ts ... > A, size_ template < class ... Ts > bool any ( const ext::vector < bool, Ts ... > & v ) { - size_t sizeWithin = v.size ( ) % vectorBoolInternalTypeInBits; + // c++ implementation-specific + /*typename ext::vector < bool, Ts ... >::const_iterator itV = v.begin ( ); - typename ext::vector < bool, Ts ... >::const_iterator itV = v.begin ( ); + size_t sizeWithin = v.size ( ) % vectorBoolInternalTypeInBits; - // c++ implementation-specific while ( itV + 1 < v.end ( ) ) if ( * ( itV._M_p ++ ) != 0 ) return true; - if ( sizeWithin == 0 ) - return * itV._M_p != 0; - else - return ( * itV._M_p & getMask ( sizeWithin ) ) != 0; + return ( * itV._M_p & getMask ( sizeWithin ) ) != 0;*/ + + // c++ compilant + typename ext::vector < bool, Ts ... >::const_iterator itV = v.begin ( ); + for ( ; itV != v.end ( ); ++ itV ) + if ( * itV ) + return true; + + return false; } template < class ... Ts > void fill ( ext::vector < bool, Ts ... > & v ) { - typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( ); - // c++ implementation-specific + /*typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( ); + while ( itV < v.end ( ) ) - * ( itV._M_p ++ ) = ~ vectorBoolInternalType { }; + * ( itV._M_p ++ ) = ~ vectorBoolInternalType { };*/ + + // c++ compilant + typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( ); + for ( ; itV != v.end ( ); ++ itV ) + * itV = true; } template < class ... Ts > void clear ( ext::vector < bool, Ts ... > & v ) { - typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( ); - // c++ implementation-specific + /* typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( ); + while ( itV < v.end ( ) ) - * ( itV._M_p ++ ) = 0; + * ( itV._M_p ++ ) = 0;*/ + + // c++ compilant + typename ext::vector < bool, Ts ... >::iterator itV = v.begin ( ); + for ( ; itV != v.end ( ); ++ itV ) + * itV = false; } } /* namespace ext */ diff --git a/alib2std/test-src/extensions/VectorTest.cpp b/alib2std/test-src/extensions/VectorTest.cpp index 2857ae9caf..8da02afced 100644 --- a/alib2std/test-src/extensions/VectorTest.cpp +++ b/alib2std/test-src/extensions/VectorTest.cpp @@ -313,3 +313,21 @@ void VectorTest::testVectorBool5() { CPPUNIT_ASSERT ( data2 == data ); } +void VectorTest::testVectorBool6 ( ) { + for ( size_t i = 1; i < 1000; i += 31 ) { + for ( size_t j = 1; j < 1000; j += 31 ) { + ext::vector < bool > first; + ext::vector < bool > second; + + first.resize ( i ); + second.resize ( j ); + + ext::fill ( first ); + ext::clear ( second ); + + ext::vector < bool > res = first & second; + + CPPUNIT_ASSERT ( ext::any ( res ) == false ); + } + } +} diff --git a/alib2std/test-src/extensions/VectorTest.h b/alib2std/test-src/extensions/VectorTest.h index e036ce2083..a070c9ec3f 100644 --- a/alib2std/test-src/extensions/VectorTest.h +++ b/alib2std/test-src/extensions/VectorTest.h @@ -13,6 +13,7 @@ class VectorTest : public CppUnit::TestFixture CPPUNIT_TEST( testVectorBool3 ); CPPUNIT_TEST( testVectorBool4 ); CPPUNIT_TEST( testVectorBool5 ); + CPPUNIT_TEST( testVectorBool6 ); CPPUNIT_TEST_SUITE_END(); public: @@ -59,6 +60,7 @@ public: void testVectorBool3(); void testVectorBool4(); void testVectorBool5(); + void testVectorBool6(); }; #endif // VECTOR_TEST_H_ -- GitLab