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/detail/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()56 int 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