#include "ParamPassTest.h" #include <exception> #include <utility> #include <memory> #include <type_traits> CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( ParamPassTest, "bits" ); CPPUNIT_TEST_SUITE_REGISTRATION ( ParamPassTest ); void ParamPassTest::setUp ( ) { } void ParamPassTest::tearDown ( ) { } int instances = 0; class FooCloneable { int data; FooCloneable ( const FooCloneable & foo ) : data ( foo.data ) { std::cout << "Copy" << std::endl; instances++; } FooCloneable ( FooCloneable && foo ) : data ( foo.data ) { std::cout << "Move" << std::endl; instances++; } public: FooCloneable ( int data ) : data ( data ) { std::cout << "Constructor" << std::endl; instances++; } ~FooCloneable ( ) { std::cout << "Destructor" << std::endl; instances--; } FooCloneable * clone ( ) const { return new FooCloneable ( * this ); } int getData ( ) const { return data; } }; class FooCopyable { int data; public: FooCopyable ( int data ) : data ( data ) { std::cout << "Constructor" << std::endl; instances++; } FooCopyable ( const FooCopyable & foo ) : data ( foo.data ) { std::cout << "Copy" << std::endl; instances++; } FooCopyable ( FooCopyable && foo ) : data ( foo.data ) { std::cout << "Move" << std::endl; instances++; } ~FooCopyable ( ) { std::cout << "Destructor" << std::endl; instances--; } FooCopyable * clone ( ) const { return new FooCopyable ( * this ); } int getData ( ) const { return data; } }; int dest ( FooCloneable && foo ) { std::cout << "Destination called" << std::endl; if ( instances < 2 ) throw std::exception ( ); return foo.getData ( ); } int dest ( FooCopyable && foo ) { std::cout << "Destination called" << std::endl; if ( instances < 2 ) throw std::exception ( ); return foo.getData ( ); } int test ( FooCloneable && foo ) { return dest ( std::move ( foo ) ); } int test ( const FooCloneable & foo ) { return test ( std::move_copy ( foo ) ); } int test ( FooCopyable && foo ) { return dest ( std::move ( foo ) ); } int test ( const FooCopyable & foo ) { return test ( std::move_copy ( foo ) ); } void ParamPassTest::testParameterPassing ( ) { { const FooCloneable foo ( 1 ); int res = 0; CPPUNIT_ASSERT_NO_THROW ( res = test ( foo ) ); CPPUNIT_ASSERT ( res == 1 && instances == 1 ); } { const FooCopyable foo ( 1 ); int res = 0; CPPUNIT_ASSERT_NO_THROW ( res = test ( foo ) ); CPPUNIT_ASSERT ( res == 1 && instances == 1 ); } }