1 // make_shared_move_emulation_test.cpp - a test of make_shared 2 // semi-perfect forwarding of constructor arguments when using a C++03 3 // compiler with move emulation. 4 // Note the "semi": it means moving temporaries (real r-values) doesn't work. 5 // 6 // Copyright 2016 Giel van Schijndel 7 // 8 // Distributed under the Boost Software License, Version 1.0. 9 // See accompanying file LICENSE_1_0.txt or copy at 10 // http://www.boost.org/LICENSE_1_0.txt 11 12 #include <boost/core/lightweight_test.hpp> 13 #include <boost/make_shared.hpp> 14 #include <boost/move/core.hpp> 15 #include <boost/move/utility_core.hpp> 16 #include <boost/shared_ptr.hpp> 17 18 class movearg 19 { 20 private: 21 BOOST_MOVABLE_BUT_NOT_COPYABLE(movearg) 22 public: movearg()23 movearg() 24 {} movearg(BOOST_RV_REF (movearg))25 movearg(BOOST_RV_REF(movearg)) 26 {} operator =(BOOST_RV_REF (movearg))27 movearg& operator=(BOOST_RV_REF(movearg)) 28 { 29 return *this; 30 } 31 }; 32 33 class ByVal 34 { 35 public: ByVal(movearg)36 ByVal(movearg) {} 37 }; 38 39 class ByRef 40 { 41 public: 42 enum constructor_id 43 { 44 move_constructor, 45 const_ref_constructor 46 }; 47 ByRef(BOOST_RV_REF (movearg))48 ByRef(BOOST_RV_REF(movearg)): constructed_by_(move_constructor) 49 {} ByRef(const movearg & arg)50 ByRef(const movearg &arg): constructed_by_(const_ref_constructor) 51 {} 52 53 constructor_id constructed_by_; 54 }; 55 main()56int main() 57 { 58 { 59 movearg a; 60 boost::shared_ptr< ByVal > x = boost::make_shared< ByVal >(boost::move(a)); 61 } 62 { 63 movearg a; 64 boost::shared_ptr< ByRef > x = boost::make_shared< ByRef >(boost::move(a)); 65 BOOST_TEST( x->constructed_by_ == ByRef::move_constructor); 66 } 67 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 68 { 69 boost::shared_ptr< ByVal > x = boost::make_shared< ByVal >(movearg()); 70 boost::shared_ptr< ByRef > y = boost::make_shared< ByRef >(movearg()); 71 BOOST_TEST( y->constructed_by_ == ByRef::move_constructor); 72 } 73 #endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 74 { 75 const movearg ca; 76 boost::shared_ptr< ByRef > x = boost::make_shared< ByRef >(ca); 77 BOOST_TEST( x->constructed_by_ == ByRef::const_ref_constructor); 78 } 79 80 return boost::report_errors(); 81 } 82