corelib/tests/variant.cc

1016 lines
29 KiB
C++

#include <lw/lib/Types.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
class VariantTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( VariantTest );
CPPUNIT_TEST( testEmpty );
CPPUNIT_TEST( testValueCopyCons );
CPPUNIT_TEST( testValueMoveCons );
CPPUNIT_TEST( testValueCopyAss );
CPPUNIT_TEST( testValueMoveAss );
CPPUNIT_TEST( testValueNoMoveCons );
CPPUNIT_TEST( testValueNoMoveAss );
CPPUNIT_TEST( testLargeCopyCons );
CPPUNIT_TEST( testLargeMoveCons );
CPPUNIT_TEST( testLargeCopyAss );
CPPUNIT_TEST( testLargeMoveAss );
CPPUNIT_TEST( testLIPCopyCons );
CPPUNIT_TEST( testLIPMoveCons );
CPPUNIT_TEST( testLIPCopyAss );
CPPUNIT_TEST( testLIPMoveAss );
CPPUNIT_TEST( testValueRead );
CPPUNIT_TEST( testLargeRead );
CPPUNIT_TEST( testLIPRead );
CPPUNIT_TEST( testValueReadBadType );
CPPUNIT_TEST( testValueWrite );
CPPUNIT_TEST( testLargeWrite );
CPPUNIT_TEST( testLIPWrite );
CPPUNIT_TEST( testValueWriteBadType );
CPPUNIT_TEST( testCopyConsSmall );
CPPUNIT_TEST( testCopyConsLarge );
CPPUNIT_TEST( testCopyConsLIP );
CPPUNIT_TEST( testCopyAssSmall );
CPPUNIT_TEST( testCopyAssLarge );
CPPUNIT_TEST( testCopyAssLIP );
CPPUNIT_TEST( testMoveConsSmall );
CPPUNIT_TEST( testMoveConsLarge );
CPPUNIT_TEST( testMoveConsLIP );
CPPUNIT_TEST( testMoveAssSmall );
CPPUNIT_TEST( testMoveAssLarge );
CPPUNIT_TEST( testMoveAssLIP );
CPPUNIT_TEST( testSwapSS );
CPPUNIT_TEST( testSwapLL );
CPPUNIT_TEST( testSwapSL );
CPPUNIT_TEST( testSwapES );
CPPUNIT_TEST( testSwapEL );
CPPUNIT_TEST( testSwapLIPSS );
CPPUNIT_TEST( testSwapLIPLL );
CPPUNIT_TEST( testSwapLIPSL );
CPPUNIT_TEST( testSwapLIPES );
CPPUNIT_TEST( testSwapLIPEL );
CPPUNIT_TEST( testCopyConsLIPToSmall );
CPPUNIT_TEST( testCopyConsLIPToLarge );
CPPUNIT_TEST( testCopyConsSmallToLIP );
CPPUNIT_TEST( testCopyConsLargeToLIP );
CPPUNIT_TEST( testMoveConsLIPToSmall );
CPPUNIT_TEST( testMoveConsLIPToLarge );
CPPUNIT_TEST( testMoveConsSmallToLIP );
CPPUNIT_TEST( testMoveConsLargeToLIP );
CPPUNIT_TEST( testCopyAssLIPToSmall );
CPPUNIT_TEST( testCopyAssLIPToLarge );
CPPUNIT_TEST( testCopyAssSmallToLIP );
CPPUNIT_TEST( testCopyAssLargeToLIP );
CPPUNIT_TEST( testMoveAssLIPToSmall );
CPPUNIT_TEST( testMoveAssLIPToLarge );
CPPUNIT_TEST( testMoveAssSmallToLIP );
CPPUNIT_TEST( testMoveAssLargeToLIP );
CPPUNIT_TEST_SUITE_END( );
public:
void tearDown( ) override;
void testEmpty( );
void testValueCopyCons( );
void testValueMoveCons( );
void testValueCopyAss( );
void testValueMoveAss( );
void testValueNoMoveCons( );
void testValueNoMoveAss( );
void testLargeCopyCons( );
void testLargeMoveCons( );
void testLargeCopyAss( );
void testLargeMoveAss( );
void testLIPCopyCons( );
void testLIPMoveCons( );
void testLIPCopyAss( );
void testLIPMoveAss( );
void testValueRead( );
void testLargeRead( );
void testLIPRead( );
void testValueReadBadType( );
void testValueWrite( );
void testLargeWrite( );
void testLIPWrite( );
void testValueWriteBadType( );
void testCopyConsSmall( );
void testCopyConsLarge( );
void testCopyConsLIP( );
void testCopyAssSmall( );
void testCopyAssLarge( );
void testCopyAssLIP( );
void testMoveConsSmall( );
void testMoveConsLarge( );
void testMoveConsLIP( );
void testMoveAssSmall( );
void testMoveAssLarge( );
void testMoveAssLIP( );
void testSwapSS( );
void testSwapLL( );
void testSwapSL( );
void testSwapES( );
void testSwapEL( );
void testSwapLIPSS( );
void testSwapLIPLL( );
void testSwapLIPSL( );
void testSwapLIPES( );
void testSwapLIPEL( );
void testCopyConsLIPToSmall( );
void testCopyConsLIPToLarge( );
void testCopyConsSmallToLIP( );
void testCopyConsLargeToLIP( );
void testMoveConsLIPToSmall( );
void testMoveConsLIPToLarge( );
void testMoveConsSmallToLIP( );
void testMoveConsLargeToLIP( );
void testCopyAssLIPToSmall( );
void testCopyAssLIPToLarge( );
void testCopyAssSmallToLIP( );
void testCopyAssLargeToLIP( );
void testMoveAssLIPToSmall( );
void testMoveAssLIPToLarge( );
void testMoveAssSmallToLIP( );
void testMoveAssLargeToLIP( );
};
CPPUNIT_TEST_SUITE_REGISTRATION( VariantTest );
/*----------------------------------------------------------------------------*/
namespace {
struct T_Base
{
static int copies;
static int moves;
static void reset( ) { copies = moves = 0; }
};
int T_Base::copies = 0;
int T_Base::moves = 0;
struct T_Obj : public T_Base
{
uint32_t v;
T_Obj( ) : T_Obj( 0 ) { }
T_Obj( uint32_t v ) : v( v ) { }
T_Obj( T_Obj const& o ) : T_Obj( o.v ) { copies ++; }
T_Obj& operator =( T_Obj const& o ) { v = o.v; copies ++; return *this; }
T_Obj( T_Obj&& o ) noexcept : T_Obj( o.v ) { moves ++; }
T_Obj& operator =( T_Obj&& o ) noexcept { v = o.v; moves ++; return *this; }
};
struct T_ObjCopy : public T_Base
{
uint32_t v;
T_ObjCopy( ) : T_ObjCopy( 0 ) { }
T_ObjCopy( uint32_t v ) : v( v ) { }
T_ObjCopy( T_ObjCopy const& o ) : T_ObjCopy( o.v ) { copies ++; }
T_ObjCopy& operator =( T_ObjCopy const& o ) { v = o.v; copies ++; return *this; }
T_ObjCopy( T_ObjCopy&& o ) noexcept = delete;
T_ObjCopy& operator =( T_ObjCopy&& o ) noexcept = delete;
};
struct T_ObjLarge : public T_Base
{
uint32_t v[ 32 ];
T_ObjLarge( ) : T_ObjLarge( 0 ) { }
T_ObjLarge( uint32_t value )
{
for ( uint32_t i = 0 ; i < sizeof( v ) / sizeof( uint32_t ) ; i ++ ) {
v[ i ] = value;
}
}
T_ObjLarge( T_ObjLarge const& o ) : T_ObjLarge( o.v[ 0 ] ) { copies ++; }
T_ObjLarge& operator =( T_ObjLarge const& o )
{
memcpy( v , o.v , sizeof( v ) );
copies ++;
return *this;
}
T_ObjLarge( T_ObjLarge&& o ) noexcept : T_ObjLarge( o.v[ 0 ] ) { moves ++; }
T_ObjLarge& operator =( T_ObjLarge&& o ) noexcept
{
memcpy( v , o.v , sizeof( v ) );
moves ++;
return *this;
}
};
static_assert( sizeof( T_Obj ) <= sizeof( void* ) && alignof( T_Obj ) <= alignof( void * ) ,
"T_Obj would not be stored in-place" );
static_assert( sizeof( T_ObjCopy ) <= sizeof( void* ) && alignof( T_ObjCopy ) <= alignof( void * ) ,
"T_ObjCopy would not be stored in-place" );
static_assert( sizeof( T_ObjLarge ) > sizeof( void* ) || alignof( T_ObjLarge ) > alignof( void * ) ,
"T_ObjLarge would be stored in-place" );
using T_LIP_ = T_VariantExt< sizeof( T_ObjLarge ) >;
template< typename Type , size_t S >
bool IsInPlace( T_VariantExt< S > const* container ,
Type const* contained ) noexcept
{
char const* cStart( (char const*) container );
char const* cEnd( cStart + sizeof( T_VariantExt< S > ) );
char const* oStart( (char const*) contained );
char const* oEnd( oStart + sizeof( Type ) );
return oStart >= cStart && oEnd <= cEnd;
}
#define M_INPLACE( Container , Type ) \
IsInPlace( &Container , &( Container.value< Type >( ) ) )
}
void VariantTest::tearDown( )
{
T_Base::reset( );
}
/*----------------------------------------------------------------------------*/
void VariantTest::testEmpty( )
{
T_Variant test;
CPPUNIT_ASSERT( !bool( test ) );
CPPUNIT_ASSERT( !test );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( void ) );
}
/*----------------------------------------------------------------------------*/
void VariantTest::testValueCopyCons( )
{
T_Obj init( 12 );
T_Variant test( init );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( M_INPLACE( test , T_Obj ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testValueMoveCons( )
{
T_Variant test( T_Obj( 12 ) );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( M_INPLACE( test , T_Obj ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testValueCopyAss( )
{
T_Obj init( 12 );
T_Variant test;
test = init;
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( M_INPLACE( test , T_Obj ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testValueMoveAss( )
{
T_Variant test;
test = T_Obj( 12 );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( M_INPLACE( test , T_Obj ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testValueNoMoveCons( )
{
T_Variant test( T_ObjCopy( 12 ) );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjCopy ) );
CPPUNIT_ASSERT( !M_INPLACE( test , T_ObjCopy ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testValueNoMoveAss( )
{
T_Variant test;
test = T_ObjCopy( 12 );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjCopy ) );
CPPUNIT_ASSERT( !M_INPLACE( test , T_ObjCopy ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
/*----------------------------------------------------------------------------*/
void VariantTest::testLargeCopyCons( )
{
T_ObjLarge init( 12 );
T_Variant test( init );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( !M_INPLACE( test , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testLargeMoveCons( )
{
T_Variant test( T_ObjLarge( 12 ) );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( !M_INPLACE( test , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testLargeCopyAss( )
{
T_ObjLarge init( 12 );
T_Variant test;
test = init;
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( !M_INPLACE( test , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testLargeMoveAss( )
{
T_Variant test;
test = T_ObjLarge( 12 );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( !M_INPLACE( test , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
/*----------------------------------------------------------------------------*/
void VariantTest::testLIPCopyCons( )
{
T_ObjLarge init( 12 );
T_LIP_ test( init );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( M_INPLACE( test , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testLIPMoveCons( )
{
T_LIP_ test( T_ObjLarge( 12 ) );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( M_INPLACE( test , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testLIPCopyAss( )
{
T_ObjLarge init( 12 );
T_LIP_ test;
test = init;
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( M_INPLACE( test , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testLIPMoveAss( )
{
T_LIP_ test;
test = T_ObjLarge( 12 );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( !( !test ) );
CPPUNIT_ASSERT( test.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( M_INPLACE( test , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
/*----------------------------------------------------------------------------*/
void VariantTest::testValueRead( )
{
T_Variant test( T_Obj( 12 ) );
CPPUNIT_ASSERT( test.value< T_Obj >( ).v == 12 );
}
void VariantTest::testLargeRead( )
{
T_Variant test( T_ObjLarge( 12 ) );
CPPUNIT_ASSERT( test.value< T_ObjLarge >( ).v[ 0 ] == 12 );
}
void VariantTest::testLIPRead( )
{
T_LIP_ test( T_ObjLarge( 12 ) );
CPPUNIT_ASSERT( test.value< T_ObjLarge >( ).v[ 0 ] == 12 );
}
void VariantTest::testValueReadBadType( )
{
T_Variant test( T_ObjCopy( 12 ) );
try {
test.value< T_Obj >( );
CPPUNIT_FAIL( "exception not thrown" );
} catch ( std::bad_cast const& ) { }
}
void VariantTest::testValueWrite( )
{
T_Variant test( T_Obj( 1 ) );
test.value< T_Obj >( ).v = 2;
CPPUNIT_ASSERT( test.value< T_Obj >( ).v == 2 );
}
void VariantTest::testLargeWrite( )
{
T_Variant test( T_ObjLarge( 1 ) );
test.value< T_ObjLarge >( ).v[ 5 ] = 2;
CPPUNIT_ASSERT( test.value< T_ObjLarge >( ).v[ 5 ] == 2 );
}
void VariantTest::testLIPWrite( )
{
T_Variant test( T_ObjLarge( 1 ) );
test.value< T_ObjLarge >( ).v[ 5 ] = 2;
CPPUNIT_ASSERT( test.value< T_ObjLarge >( ).v[ 5 ] == 2 );
}
void VariantTest::testValueWriteBadType( )
{
T_Variant test( T_ObjCopy( 12 ) );
try {
test.value< T_Obj >( ).v = 1;
CPPUNIT_FAIL( "exception not thrown" );
} catch ( std::bad_cast const& ) { }
}
/*----------------------------------------------------------------------------*/
void VariantTest::testCopyConsSmall( )
{
T_Variant test( T_Obj( 1 ) );
T_Base::reset( );
T_Variant copy( test );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( copy.value< T_Obj >( ).v == 1 );
CPPUNIT_ASSERT( M_INPLACE( copy , T_Obj ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testCopyConsLarge( )
{
T_Variant test( T_ObjLarge( 1 ) );
T_Base::reset( );
T_Variant copy( test );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( copy.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT( !M_INPLACE( copy , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testCopyConsLIP( )
{
T_LIP_ test( T_ObjLarge( 1 ) );
T_Base::reset( );
T_LIP_ copy( test );
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( copy.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT( M_INPLACE( copy , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testCopyAssSmall( )
{
T_Variant test( T_Obj( 1 ) );
T_Base::reset( );
T_Variant copy;
copy = test;
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( copy.value< T_Obj >( ).v == 1 );
CPPUNIT_ASSERT( M_INPLACE( copy , T_Obj ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testCopyAssLarge( )
{
T_Variant test( T_ObjLarge( 1 ) );
T_Base::reset( );
T_Variant copy;
copy = test;
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( copy.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT( !M_INPLACE( copy , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testCopyAssLIP( )
{
T_LIP_ test( T_ObjLarge( 1 ) );
T_Base::reset( );
T_LIP_ copy;
copy = test;
CPPUNIT_ASSERT( bool( test ) );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( copy.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT( M_INPLACE( copy , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testMoveConsSmall( )
{
T_Variant test( T_Obj( 1 ) );
T_Base::reset( );
T_Variant copy( std::move( test ) );
CPPUNIT_ASSERT( !test );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( copy.value< T_Obj >( ).v == 1 );
CPPUNIT_ASSERT( M_INPLACE( copy , T_Obj ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testMoveConsLarge( )
{
T_Variant test( T_ObjLarge( 1 ) );
T_Base::reset( );
T_Variant copy( std::move( test ) );
CPPUNIT_ASSERT( !test );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( copy.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT( !M_INPLACE( copy , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testMoveConsLIP( )
{
T_LIP_ test( T_ObjLarge( 1 ) );
T_Base::reset( );
T_LIP_ copy( std::move( test ) );
CPPUNIT_ASSERT( !test );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( copy.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT( M_INPLACE( copy , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testMoveAssSmall( )
{
T_Variant test( T_Obj( 1 ) );
T_Base::reset( );
T_Variant copy;
copy = std::move( test );
CPPUNIT_ASSERT( !test );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( copy.value< T_Obj >( ).v == 1 );
CPPUNIT_ASSERT( M_INPLACE( copy , T_Obj ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testMoveAssLarge( )
{
T_Variant test( T_ObjLarge( 1 ) );
T_Base::reset( );
T_Variant copy;
copy = std::move( test );
CPPUNIT_ASSERT( !test );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( copy.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT( !M_INPLACE( copy , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testMoveAssLIP( )
{
T_LIP_ test( T_ObjLarge( 1 ) );
T_Base::reset( );
T_LIP_ copy;
copy = std::move( test );
CPPUNIT_ASSERT( !test );
CPPUNIT_ASSERT( bool( copy ) );
CPPUNIT_ASSERT( !( !copy ) );
CPPUNIT_ASSERT( copy.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( copy.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT( M_INPLACE( copy , T_ObjLarge ) );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
/*----------------------------------------------------------------------------*/
void VariantTest::testSwapSS( )
{
T_Variant test1( T_ObjCopy( 1 ) ) , test2( T_Obj( 2 ) );
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( test1.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( test1.value< T_Obj >( ).v == 2 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_ObjCopy ) );
CPPUNIT_ASSERT( test2.value< T_ObjCopy >( ).v == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 2 , T_Base::moves );
}
void VariantTest::testSwapLL( )
{
T_Variant test1( T_ObjLarge( 1 ) ) , test2( T_ObjLarge( 2 ) );
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( test1.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( test1.value< T_ObjLarge >( ).v[ 0 ] == 2 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( test2.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
void VariantTest::testSwapSL( )
{
T_Variant test1( T_Obj( 1 ) ) , test2( T_ObjLarge( 2 ) );
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( test1.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( test1.value< T_ObjLarge >( ).v[ 0 ] == 2 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( test2.value< T_Obj >( ).v == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testSwapES( )
{
T_Variant test1( T_Obj( 1 ) ) , test2;
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( !test1 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( test2.value< T_Obj >( ).v == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testSwapEL( )
{
T_Variant test1( T_ObjLarge( 1 ) ) , test2;
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( !test1 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( test2.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::moves );
}
/*----------------------------------------------------------------------------*/
void VariantTest::testSwapLIPSS( )
{
T_LIP_ test1( T_ObjCopy( 1 ) ) , test2( T_Obj( 2 ) );
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( test1.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( test1.value< T_Obj >( ).v == 2 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_ObjCopy ) );
CPPUNIT_ASSERT( test2.value< T_ObjCopy >( ).v == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 2 , T_Base::moves );
}
void VariantTest::testSwapLIPLL( )
{
T_LIP_ test1( T_ObjLarge( 1 ) ) , test2( T_ObjLarge( 2 ) );
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( test1.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( test1.value< T_ObjLarge >( ).v[ 0 ] == 2 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( test2.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 3 , T_Base::moves );
}
void VariantTest::testSwapLIPSL( )
{
T_LIP_ test1( T_Obj( 1 ) ) , test2( T_ObjLarge( 2 ) );
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( test1.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( test1.value< T_ObjLarge >( ).v[ 0 ] == 2 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( test2.value< T_Obj >( ).v == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 3 , T_Base::moves );
}
void VariantTest::testSwapLIPES( )
{
T_LIP_ test1( T_Obj( 1 ) ) , test2;
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( !test1 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( test2.value< T_Obj >( ).v == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
void VariantTest::testSwapLIPEL( )
{
T_LIP_ test1( T_ObjLarge( 1 ) ) , test2;
T_Base::reset( );
swap( test1 , test2 );
CPPUNIT_ASSERT( !test1 );
CPPUNIT_ASSERT( test2.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( test2.value< T_ObjLarge >( ).v[ 0 ] == 1 );
CPPUNIT_ASSERT_EQUAL( 0 , T_Base::copies );
CPPUNIT_ASSERT_EQUAL( 1 , T_Base::moves );
}
/*----------------------------------------------------------------------------*/
void VariantTest::testCopyConsLIPToSmall( )
{
T_LIP_ src( T_Obj( 12 ) );
T_Variant dest( src );
CPPUNIT_ASSERT( bool( src ) );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( dest.value< T_Obj >( ).v == 12 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_Obj ) );
}
void VariantTest::testCopyConsLIPToLarge( )
{
T_LIP_ src( T_ObjLarge( 12 ) );
T_Variant dest( src );
CPPUNIT_ASSERT( bool( src ) );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( dest.value< T_ObjLarge >( ).v[ 0 ] == 12 );
CPPUNIT_ASSERT( !M_INPLACE( dest , T_ObjLarge ) );
}
void VariantTest::testCopyConsSmallToLIP( )
{
T_Variant src( T_Obj( 2 ) );
T_LIP_ dest( src );
CPPUNIT_ASSERT( bool( src ) );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( dest.value< T_Obj >( ).v == 2 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_Obj ) );
}
void VariantTest::testCopyConsLargeToLIP( )
{
T_Variant src( T_ObjLarge( 12 ) );
T_LIP_ dest( src );
CPPUNIT_ASSERT( bool( src ) );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( dest.value< T_ObjLarge >( ).v[ 0 ] == 12 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_ObjLarge ) );
}
void VariantTest::testMoveConsLIPToSmall( )
{
T_LIP_ src( T_Obj( 12 ) );
T_Variant dest( std::move( src ) );
CPPUNIT_ASSERT( !src );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( dest.value< T_Obj >( ).v == 12 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_Obj ) );
}
void VariantTest::testMoveConsLIPToLarge( )
{
T_LIP_ src( T_ObjLarge( 12 ) );
T_Variant dest( std::move( src ) );
CPPUNIT_ASSERT( !src );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( dest.value< T_ObjLarge >( ).v[ 0 ] == 12 );
CPPUNIT_ASSERT( !M_INPLACE( dest , T_ObjLarge ) );
}
void VariantTest::testMoveConsSmallToLIP( )
{
T_Variant src( T_Obj( 12 ) );
T_LIP_ dest( std::move( src ) );
CPPUNIT_ASSERT( !src );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( dest.value< T_Obj >( ).v == 12 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_Obj ) );
}
void VariantTest::testMoveConsLargeToLIP( )
{
T_Variant src( T_ObjLarge( 12 ) );
T_LIP_ dest( std::move( src ) );
CPPUNIT_ASSERT( !src );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( dest.value< T_ObjLarge >( ).v[ 0 ] == 12 );
CPPUNIT_ASSERT( !M_INPLACE( dest , T_ObjLarge ) );
}
void VariantTest::testCopyAssLIPToSmall( )
{
T_LIP_ src( T_Obj( 12 ) );
T_Variant dest;
dest = src;
CPPUNIT_ASSERT( bool( src ) );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( dest.value< T_Obj >( ).v == 12 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_Obj ) );
}
void VariantTest::testCopyAssLIPToLarge( )
{
T_LIP_ src( T_ObjLarge( 12 ) );
T_Variant dest;
dest = src;
CPPUNIT_ASSERT( bool( src ) );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( dest.value< T_ObjLarge >( ).v[ 0 ] == 12 );
CPPUNIT_ASSERT( !M_INPLACE( dest , T_ObjLarge ) );
}
void VariantTest::testCopyAssSmallToLIP( )
{
T_Variant src( T_Obj( 2 ) );
T_LIP_ dest;
dest = src;
CPPUNIT_ASSERT( bool( src ) );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( dest.value< T_Obj >( ).v == 2 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_Obj ) );
}
void VariantTest::testCopyAssLargeToLIP( )
{
T_Variant src( T_ObjLarge( 12 ) );
T_LIP_ dest;
dest = src;
CPPUNIT_ASSERT( bool( src ) );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( dest.value< T_ObjLarge >( ).v[ 0 ] == 12 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_ObjLarge ) );
}
void VariantTest::testMoveAssLIPToSmall( )
{
T_LIP_ src( T_Obj( 12 ) );
T_Variant dest;
dest = std::move( src );
CPPUNIT_ASSERT( !src );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( dest.value< T_Obj >( ).v == 12 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_Obj ) );
}
void VariantTest::testMoveAssLIPToLarge( )
{
T_LIP_ src( T_ObjLarge( 12 ) );
T_Variant dest;
dest = std::move( src );
CPPUNIT_ASSERT( !src );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( dest.value< T_ObjLarge >( ).v[ 0 ] == 12 );
CPPUNIT_ASSERT( !M_INPLACE( dest , T_ObjLarge ) );
}
void VariantTest::testMoveAssSmallToLIP( )
{
T_Variant src( T_Obj( 2 ) );
T_LIP_ dest;
dest = std::move( src );
CPPUNIT_ASSERT( !src );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_Obj ) );
CPPUNIT_ASSERT( dest.value< T_Obj >( ).v == 2 );
CPPUNIT_ASSERT( M_INPLACE( dest , T_Obj ) );
}
void VariantTest::testMoveAssLargeToLIP( )
{
T_Variant src( T_ObjLarge( 12 ) );
T_LIP_ dest;
dest = std::move( src );
CPPUNIT_ASSERT( !src );
CPPUNIT_ASSERT( bool( dest ) );
CPPUNIT_ASSERT( dest.typeInfo( ) == typeid( T_ObjLarge ) );
CPPUNIT_ASSERT( dest.value< T_ObjLarge >( ).v[ 0 ] == 12 );
CPPUNIT_ASSERT( !M_INPLACE( dest , T_ObjLarge ) );
}