Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81131 - in trunk: boost/smart_ptr boost/smart_ptr/detail libs/smart_ptr/test
From: pdimov_at_[hidden]
Date: 2012-10-31 18:16:21


Author: pdimov
Date: 2012-10-31 18:16:20 EDT (Wed, 31 Oct 2012)
New Revision: 81131
URL: http://svn.boost.org/trac/boost/changeset/81131

Log:
Add shared_ptr constructor taking std::unique_ptr. Refs #6625.
Added:
   trunk/libs/smart_ptr/test/sp_unique_ptr_test.cpp (contents, props changed)
Text files modified:
   trunk/boost/smart_ptr/detail/shared_count.hpp | 63 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/smart_ptr/shared_ptr.hpp | 12 +++++++
   trunk/libs/smart_ptr/test/Jamfile.v2 | 1
   3 files changed, 76 insertions(+), 0 deletions(-)

Modified: trunk/boost/smart_ptr/detail/shared_count.hpp
==============================================================================
--- trunk/boost/smart_ptr/detail/shared_count.hpp (original)
+++ trunk/boost/smart_ptr/detail/shared_count.hpp 2012-10-31 18:16:20 EDT (Wed, 31 Oct 2012)
@@ -37,6 +37,10 @@
 #include <functional> // std::less
 #include <new> // std::bad_alloc
 
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+# include <boost/utility/addressof.hpp>
+#endif
+
 namespace boost
 {
 
@@ -56,6 +60,38 @@
 {
 };
 
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+template< class T > class sp_reference_wrapper
+{
+public:
+
+ explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
+ {
+ }
+
+ template< class Y > void operator()( Y * p ) const
+ {
+ (*t_)( p );
+ }
+
+private:
+
+ T * t_;
+};
+
+template< class D > struct sp_convert_reference
+{
+ typedef D type;
+};
+
+template< class D > struct sp_convert_reference< D& >
+{
+ typedef sp_reference_wrapper< D > type;
+};
+
+#endif
+
 class weak_count;
 
 class shared_count
@@ -300,6 +336,33 @@
 
 #endif
 
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+ template<class Y, class D>
+ explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ typedef typename sp_convert_reference<D>::type D2;
+
+ D2 d2( r.get_deleter() );
+ pi_ = new sp_counted_impl_pd< Y*, D2 >( r.get(), d2 );
+
+#ifdef BOOST_NO_EXCEPTIONS
+
+ if( pi_ == 0 )
+ {
+ boost::throw_exception( std::bad_alloc() );
+ }
+
+#endif
+
+ r.release();
+ }
+
+#endif
+
     ~shared_count() // nothrow
     {
         if( pi_ != 0 ) pi_->release();

Modified: trunk/boost/smart_ptr/shared_ptr.hpp
==============================================================================
--- trunk/boost/smart_ptr/shared_ptr.hpp (original)
+++ trunk/boost/smart_ptr/shared_ptr.hpp 2012-10-31 18:16:20 EDT (Wed, 31 Oct 2012)
@@ -298,6 +298,18 @@
 
 #endif // BOOST_NO_AUTO_PTR
 
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+ template< class Y, class D >
+ shared_ptr( std::unique_ptr< Y, D > && r): px( r.get() ), pn()
+ {
+ Y * tmp = r.get();
+ pn = boost::detail::shared_count( r );
+ boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
+ }
+
+#endif
+
     // assignment
 
     shared_ptr & operator=( shared_ptr const & r ) // never throws

Modified: trunk/libs/smart_ptr/test/Jamfile.v2
==============================================================================
--- trunk/libs/smart_ptr/test/Jamfile.v2 (original)
+++ trunk/libs/smart_ptr/test/Jamfile.v2 2012-10-31 18:16:20 EDT (Wed, 31 Oct 2012)
@@ -69,5 +69,6 @@
           [ run get_deleter_array_test.cpp ]
           [ run ip_hash_test.cpp ]
           [ run owner_less_test.cpp ]
+ [ run sp_unique_ptr_test.cpp ]
         ;
 }

Added: trunk/libs/smart_ptr/test/sp_unique_ptr_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/sp_unique_ptr_test.cpp 2012-10-31 18:16:20 EDT (Wed, 31 Oct 2012)
@@ -0,0 +1,152 @@
+//
+// sp_unique_ptr_test.cpp
+//
+// Copyright (c) 2012 Peter Dimov
+//
+// 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 <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <memory>
+#include <utility>
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+struct X: public boost::enable_shared_from_this< X >
+{
+ static int instances;
+
+ X()
+ {
+ ++instances;
+ }
+
+ ~X()
+ {
+ --instances;
+ }
+
+private:
+
+ X( X const & );
+ X & operator=( X const & );
+};
+
+int X::instances = 0;
+
+struct Y
+{
+ static int instances;
+
+ bool deleted_;
+
+ Y(): deleted_( false )
+ {
+ ++instances;
+ }
+
+ ~Y()
+ {
+ BOOST_TEST( deleted_ );
+ --instances;
+ }
+
+private:
+
+ Y( Y const & );
+ Y & operator=( Y const & );
+};
+
+int Y::instances = 0;
+
+struct YD
+{
+ void operator()( Y* p ) const
+ {
+ p->deleted_ = true;
+ delete p;
+ }
+};
+
+int main()
+{
+ {
+ BOOST_TEST( X::instances == 0 );
+
+ std::unique_ptr<X> p( new X );
+ BOOST_TEST( X::instances == 1 );
+
+ boost::shared_ptr<X> p2( std::move( p ) );
+ BOOST_TEST( X::instances == 1 );
+ BOOST_TEST( p.get() == 0 );
+
+ boost::shared_ptr<X> p3 = p2->shared_from_this();
+ BOOST_TEST( p2 == p3 );
+ BOOST_TEST( !(p2 < p3) && !(p3 < p2) );
+
+ p2.reset();
+ p3.reset();
+ BOOST_TEST( X::instances == 0 );
+ }
+
+ {
+ BOOST_TEST( Y::instances == 0 );
+
+ std::unique_ptr<Y, YD> p( new Y, YD() );
+ BOOST_TEST( Y::instances == 1 );
+
+ boost::shared_ptr<Y> p2( std::move( p ) );
+ BOOST_TEST( Y::instances == 1 );
+ BOOST_TEST( p.get() == 0 );
+
+ p2.reset();
+ BOOST_TEST( Y::instances == 0 );
+ }
+
+ {
+ BOOST_TEST( Y::instances == 0 );
+
+ YD yd;
+
+ std::unique_ptr<Y, YD&> p( new Y, yd );
+ BOOST_TEST( Y::instances == 1 );
+
+ boost::shared_ptr<Y> p2( std::move( p ) );
+ BOOST_TEST( Y::instances == 1 );
+ BOOST_TEST( p.get() == 0 );
+
+ p2.reset();
+ BOOST_TEST( Y::instances == 0 );
+ }
+
+ {
+ BOOST_TEST( Y::instances == 0 );
+
+ YD yd;
+
+ std::unique_ptr<Y, YD const&> p( new Y, yd );
+ BOOST_TEST( Y::instances == 1 );
+
+ boost::shared_ptr<Y> p2( std::move( p ) );
+ BOOST_TEST( Y::instances == 1 );
+ BOOST_TEST( p.get() == 0 );
+
+ p2.reset();
+ BOOST_TEST( Y::instances == 0 );
+ }
+
+ return boost::report_errors();
+}
+
+#else // !defined( BOOST_NO_CXX11_SMART_PTR )
+
+int main()
+{
+ return 0;
+}
+
+#endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk