diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 7e1e793..d477188 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -86,10 +86,12 @@ public: } }; -template< class T > T forward( T t ) +#if defined( BOOST_HAS_RVALUE_REFS ) +template< class T > T&& forward( T &&t ) { return t; } +#endif } // namespace detail diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index db4bfb1..d30f1ab 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -45,6 +45,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_perfect_forwarding_test.cpp ] [ run sp_convertible_test.cpp ] [ run wp_convertible_test.cpp ] [ run ip_convertible_test.cpp ] diff --git a/test/make_shared_perfect_forwarding_test.cpp b/test/make_shared_perfect_forwarding_test.cpp new file mode 100644 index 0000000..45a111c --- /dev/null +++ b/test/make_shared_perfect_forwarding_test.cpp @@ -0,0 +1,98 @@ +// make_shared_perfect_forwarding_test.cpp - a test of make_shared +// perfect forwarding of constructor arguments when using a C++0x +// compiler. +// +// Copyright 2009 Frank Mori Hess +// +// 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 + +#ifndef BOOST_HAS_RVALUE_REFS + +int main() +{ + return 0; +} + +#else // BOOST_HAS_RVALUE_REFS + +class myarg +{ +public: + myarg() + {} +private: + myarg(myarg && other) + {} + myarg& operator=(myarg && other) + { + return *this; + } + myarg(const myarg & other) + {} + myarg& operator=(const myarg & other) + { + return *this; + } +}; + +class X +{ +public: + enum constructor_id + { + move_constructor, + const_ref_constructor, + ref_constructor + }; + + X(myarg &&arg): constructed_by_(move_constructor) + {} + X(const myarg &arg): constructed_by_(const_ref_constructor) + {} + X(myarg &arg): constructed_by_(ref_constructor) + {} + + constructor_id constructed_by_; +}; + +struct Y +{ + Y(int &value): ref(value) + {} + int &ref; +}; + +int main() +{ + { + myarg a; + boost::shared_ptr< X > x = boost::make_shared< X >(a); + BOOST_TEST( x->constructed_by_ == X::ref_constructor); + } + { + const myarg ca; + boost::shared_ptr< X > x = boost::make_shared< X >(ca); + BOOST_TEST( x->constructed_by_ == X::const_ref_constructor); + } + { + boost::shared_ptr< X > x = boost::make_shared< X >(myarg()); + BOOST_TEST( x->constructed_by_ == X::move_constructor); + } + { + int value = 1; + boost::shared_ptr< Y > y = boost::make_shared< Y >(value); + BOOST_TEST( y->ref == 1 && value == y->ref ); + ++y->ref; + BOOST_TEST( value == y->ref ); + } + + return boost::report_errors(); +} + +#endif // BOOST_HAS_RVALUE_REFS