1 // make_shared_perfect_forwarding_test.cpp - a test of make_shared
2 //   perfect forwarding of constructor arguments when using a C++0x
3 //   compiler.
4 //
5 // Copyright 2009 Frank Mori Hess
6 //
7 // Distributed under the Boost Software License, Version 1.0.
8 // See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt
10 
11 #include <boost/detail/lightweight_test.hpp>
12 #include <boost/make_shared.hpp>
13 #include <boost/shared_ptr.hpp>
14 
15 #if defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
16 
main()17 int main()
18 {
19     return 0;
20 }
21 
22 #else // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
23 
24 class myarg
25 {
26 public:
myarg()27     myarg()
28     {}
29 private:
myarg(myarg && other)30     myarg(myarg && other)
31     {}
operator =(myarg && other)32     myarg& operator=(myarg && other)
33     {
34         return *this;
35     }
myarg(const myarg & other)36     myarg(const myarg & other)
37     {}
operator =(const myarg & other)38     myarg& operator=(const myarg & other)
39     {
40         return *this;
41     }
42 };
43 
44 class X
45 {
46 public:
47     enum constructor_id
48     {
49         move_constructor,
50         const_ref_constructor,
51         ref_constructor
52     };
53 
X(myarg && arg)54     X(myarg &&arg): constructed_by_(move_constructor)
55     {}
X(const myarg & arg)56     X(const myarg &arg): constructed_by_(const_ref_constructor)
57     {}
X(myarg & arg)58     X(myarg &arg): constructed_by_(ref_constructor)
59     {}
60 
61     constructor_id constructed_by_;
62 };
63 
64 struct Y
65 {
YY66     Y(int &value): ref(value)
67     {}
68     int &ref;
69 };
70 
main()71 int main()
72 {
73     {
74         myarg a;
75         boost::shared_ptr< X > x = boost::make_shared< X >(a);
76         BOOST_TEST( x->constructed_by_ == X::ref_constructor);
77     }
78     {
79         const myarg ca;
80         boost::shared_ptr< X > x = boost::make_shared< X >(ca);
81         BOOST_TEST( x->constructed_by_ == X::const_ref_constructor);
82     }
83     {
84         boost::shared_ptr< X > x = boost::make_shared< X >(myarg());
85         BOOST_TEST( x->constructed_by_ == X::move_constructor);
86     }
87     {
88         int value = 1;
89         boost::shared_ptr< Y > y = boost::make_shared< Y >(value);
90         BOOST_TEST( y->ref == 1 && value == y->ref );
91         ++y->ref;
92         BOOST_TEST( value == y->ref );
93     }
94 
95     return boost::report_errors();
96 }
97 
98 #endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
99