#include #include using namespace ebcl; 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 ) ); }