diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d965bfd..11c41c2 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -47,6 +47,7 @@ import testing ; [ run spinlock_try_test.cpp : : : multi : spinlock_try_test.mt ] [ run spinlock_pool_test.cpp ] [ run make_shared_test.cpp ] + [ run make_shared_move_emulation_test.cpp ] [ run make_shared_perfect_forwarding_test.cpp ] [ run shared_ptr_convertible_test.cpp ] [ run wp_convertible_test.cpp ] diff --git a/test/make_shared_move_emulation_test.cpp b/test/make_shared_move_emulation_test.cpp new file mode 100644 index 0000000..c607e05 --- /dev/null +++ b/test/make_shared_move_emulation_test.cpp @@ -0,0 +1,81 @@ +// make_shared_move_emulation_test.cpp - a test of make_shared +// semi-perfect forwarding of constructor arguments when using a C++03 +// compiler with move emulation. +// Note the "semi": it means moving temporaries (real r-values) doesn't work. +// +// Copyright 2016 Giel van Schijndel +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +class movearg +{ +private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(movearg) +public: + movearg() + {} + movearg(BOOST_RV_REF(movearg)) + {} + movearg& operator=(BOOST_RV_REF(movearg)) + { + return *this; + } +}; + +class ByVal +{ +public: + ByVal(movearg) {} +}; + +class ByRef +{ +public: + enum constructor_id + { + move_constructor, + const_ref_constructor + }; + + ByRef(BOOST_RV_REF(movearg)): constructed_by_(move_constructor) + {} + ByRef(const movearg &arg): constructed_by_(const_ref_constructor) + {} + + constructor_id constructed_by_; +}; + +int main() +{ + { + movearg a; + boost::shared_ptr< ByVal > x = boost::make_shared< ByVal >(boost::move(a)); + } + { + movearg a; + boost::shared_ptr< ByRef > x = boost::make_shared< ByRef >(boost::move(a)); + BOOST_TEST( x->constructed_by_ == ByRef::move_constructor); + } +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + { + boost::shared_ptr< ByVal > x = boost::make_shared< ByVal >(movearg()); + boost::shared_ptr< ByRef > y = boost::make_shared< ByRef >(movearg()); + BOOST_TEST( y->constructed_by_ == ByRef::move_constructor); + } +#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + { + const movearg ca; + boost::shared_ptr< ByRef > x = boost::make_shared< ByRef >(ca); + BOOST_TEST( x->constructed_by_ == ByRef::const_ref_constructor); + } + + return boost::report_errors(); +}