Skip to content
Snippets Groups Projects
VectorTest.cpp 9.53 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include <catch2/catch.hpp>
    
    #include <alib/vector>
    #include <alib/type_traits>
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    #include <alib/algorithm>
    
    namespace {
    	class Moveable {
    		int& m_moves;
    		int& m_copies;
    
    		public:
    		Moveable(int& moves, int& copies) : m_moves(moves), m_copies(copies) {
    			m_moves = 0;
    			m_copies = 0;
    		}
    
    		Moveable(const Moveable& src) : m_moves(src.m_moves), m_copies(src.m_copies) {
    			m_copies++;
    		}
    
    		Moveable(Moveable&& src) : m_moves(src.m_moves), m_copies(src.m_copies) {
    			m_moves++;
    		}
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    		Moveable & operator = ( const Moveable & ) {
    			m_copies ++;
    			return * this;
    		}
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    		Moveable & operator = ( Moveable && ) {
    			m_moves ++;
    			return * this;
    		}
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    		bool operator<(const Moveable&) const {
    			return false;
    		}
    	};
    }
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    TEST_CASE ( "Vector", "[unit][std][container]" ) {
    	SECTION ( "Properties test" ) {
    		ext::vector<int> data = {1, 2, 3, 4};
    
    		ext::vector<int> dataRef = {1, 2, 3, 4};
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    		const ext::vector<int>& constData = data;
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    		auto iter1 = data.erase ( data.begin ( ) );
    		CHECK ( iter1 == data.begin ( ) );
    		auto iter2 = data.erase ( data.rbegin ( ) );
    		CHECK ( iter2 == data.rbegin ( ) );
    
    		CHECK ( data.size ( ) == 2 );
    
    		auto iter3 = data.insert ( data.begin ( ), 1 );
    		CHECK ( iter3 == data.begin ( ) );
    		auto iter4 = data.insert ( data.rbegin ( ), 4 );
    		CHECK ( iter4 == data.rbegin ( ) );
    
    		CHECK ( data.size ( ) == 4 );
    
    
    		CHECK((std::is_same<decltype(constData[0]), const int&>::value));
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    		int moves;
    		int copies;
    
    		ext::vector < Moveable > vec;
    		vec.push_back ( Moveable ( moves, copies ) );
    		vec.push_back ( Moveable ( moves, copies ) );
    		vec.push_back ( Moveable ( moves, copies ) );
    		vec.push_back ( Moveable ( moves, copies ) );
    
    		vec.erase ( ext::unique ( vec.begin ( ), vec.end ( ), [ ] ( const Moveable &, const Moveable & ) { return true; } ), vec.end ( ) );
    
    		CHECK ( vec.size ( ) == 1 );
    
    		CHECK(copies == 0);
    
    	SECTION ( "Vector<bool>" ) {
    		ext::vector < bool > A;
    		A.push_back ( true );
    		A.push_back ( false );
    		A.push_back ( true );
    		A.push_back ( false );
    
    		ext::vector < bool > B;
    		B.push_back ( true );
    		B.push_back ( true );
    		B.push_back ( false );
    		B.push_back ( false );
    
    		{
    			ext::vector < bool > C = A | B;
    			ext::vector < bool > D = A;
    			D |= B;
    
    			ext::vector < bool > X;
    			X.push_back ( true );
    			X.push_back ( true );
    			X.push_back ( true );
    			X.push_back ( false );
    
    			CAPTURE ( X, C, D );
    
    			CHECK ( C == X );
    			CHECK ( D == X );
    		}
    
    		{
    			ext::vector < bool > C = A & B;
    			ext::vector < bool > D = A;
    			D &= B;
    
    			ext::vector < bool > X;
    			X.push_back ( true );
    			X.push_back ( false );
    			X.push_back ( false );
    			X.push_back ( false );
    
    			CHECK ( C == X );
    			CHECK ( D == X );
    		}
    
    		{
    			ext::vector < bool > C = A ^ B;
    			ext::vector < bool > D = A;
    			D ^= B;
    
    			ext::vector < bool > X;
    			X.push_back ( false );
    			X.push_back ( true );
    			X.push_back ( true );
    			X.push_back ( false );
    
    			CHECK ( C == X );
    			CHECK ( D == X );
    		}
    
    	SECTION ( "vector<bool> 2" ) {
    		auto testOffset = [] ( long offset, long shift ) {
    			unsigned long long shadow = 0x2A76B147D6521C87ULL;
    			ext::vector < bool > data;
    
    			for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 16 + offset; ++ i ) {
    				data.push_back ( true );
    			}
    
    			for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) {
    				data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) );
    			}
    
    			data >>= sizeof ( unsigned long long ) * 6 + shift;
    
    			ext::vector < bool > ref;
    			for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 10 + offset - shift; ++ i ) {
    				ref.push_back ( true );
    			}
    
    			for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) {
    				ref.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) );
    			}
    
    			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;*/
    
    			CHECK ( data == ref );
    		};
    
    		unsigned long long shadow = 0x2A76B147D6521C87ULL;
    		ext::vector < bool > data;
    
    		for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) {
    			data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) );
    		}
    
    		shadow >>= 10;
    		data >>= 10;
    
    		ext::vector < bool > ref;
    		for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) {
    			ref.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) );
    		}
    
    		CAPTURE ( data ,ref );
    
    		CHECK ( data == ref );
    
    		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 );
    
    	SECTION ( "vector<bool> 3" ) {
    		unsigned long long shadow = 0x2A76B147D6521C87ULL;
    		ext::vector < bool > 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 ) ) );
    		}
    
    		ext::vector < bool > data2 = data;
    		data2 >>= 64;
    
    		data >>= 32;
    		data >>= 16;
    		data >>= 8;
    		data >>= 4;
    		data >>= 2;
    		data >>= 1;
    		data >>= 1;
    
    		std::cout << "data  = " << data  << std::endl;
    		std::cout << "data2 = " << data2 << 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  << std::endl;
    		std::cout << "data2 = " << data2 << std::endl;
    
    		CHECK ( data2 == data );
    
    	SECTION ( "vector<bool> 4" ) {
    		auto testOffset = [] ( long offset, long shift ) {
    			unsigned long long shadow = 0x2A76B147D6521C87ULL;
    			ext::vector < bool > data;
    
    			for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8 + offset; ++ i ) {
    				data.push_back ( true );
    			}
    
    			for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) {
    				data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) );
    			}
    
    			data <<= sizeof ( unsigned long long ) * 2 + shift;
    
    			ext::vector < bool > ref;
    			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 );
    			}
    
    			for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) {
    				ref.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) );
    			}
    
    			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;*/
    
    			CHECK ( data == ref );
    		};
    
    		unsigned long long shadow = 0x2A76B147D6521C87ULL;
    		ext::vector < bool > data;
    
    		for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) {
    			data.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) );
    		}
    
    		shadow <<= 10;
    		data <<= 10;
    
    		ext::vector < bool > ref;
    		for ( unsigned i = 0; i < sizeof ( unsigned long long ) * 8; ++ i ) {
    			ref.push_back ( ( bool ) ( shadow & ( 1ULL << i ) ) );
    		}
    
    		std::cout << "data = " << data << std::endl;
    		std::cout << "ref  = " << ref << std::endl;
    
    		CHECK ( data == ref );
    
    		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 );
    
    	SECTION ( "vector<bool> 5" ) {
    		unsigned long long shadow = 0x2A76B147D6521C87ULL;
    		ext::vector < bool > 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 ) ) );
    		}
    
    		ext::vector < bool > data2 = data;
    		data2 <<= 64;
    
    		data <<= 32;
    		data <<= 16;
    		data <<= 8;
    		data <<= 4;
    		data <<= 2;
    		data <<= 1;
    		data <<= 1;
    
    		std::cout << "data  = " << data  << std::endl;
    		std::cout << "data2 = " << data2 << 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  << std::endl;
    		std::cout << "data2 = " << data2 << std::endl;
    
    		CHECK ( data2 == data );
    	}
    
    	SECTION ( "vector<bool> 6" ) {
    		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;
    
    				CHECK ( ext::any ( res ) == false );
    			}
    
    	SECTION ( "Test Range" ) {
    		ext::vector < int > data { 1, 2, 3, 4 };
    		ext::vector < int > data2 ( data.range ( ) );
    
    		CHECK ( data == data2 );
    
    		int moves;
    		int copies;
    
    		ext::vector < Moveable > vec;
    		vec.push_back ( Moveable ( moves, copies ) );
    		vec.push_back ( Moveable ( moves, copies ) );
    		vec.push_back ( Moveable ( moves, copies ) );
    		vec.push_back ( Moveable ( moves, copies ) );
    
    		ext::vector < Moveable > vec2 ( ext::range ( std::move ( vec ) ) );
    
    		CHECK ( copies == 0 );
    	}