-
Jan Trávníček authoredJan Trávníček authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
VectorTest.cpp 9.53 KiB
#include <catch2/catch.hpp>
#include <alib/vector>
#include <alib/type_traits>
#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++;
}
Moveable & operator = ( const Moveable & ) {
m_copies ++;
return * this;
}
Moveable & operator = ( Moveable && ) {
m_moves ++;
return * this;
}
bool operator<(const Moveable&) const {
return false;
}
};
}
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};
const ext::vector<int>& constData = data;
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));
CHECK ( data == dataRef );
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 );
}
}