Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81780 - in trunk: boost/smart_ptr boost/smart_ptr/detail libs/smart_ptr/test
From: pdimov_at_[hidden]
Date: 2012-12-07 19:52:01


Author: pdimov
Date: 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
New Revision: 81780
URL: http://svn.boost.org/trac/boost/changeset/81780

Log:
Use explicit operator bool when available; add nullptr support to shared_ptr. Refs #4116.
Added:
   trunk/libs/smart_ptr/test/sp_nullptr_test.cpp (contents, props changed)
   trunk/libs/smart_ptr/test/sp_zero_compare_test.cpp (contents, props changed)
Text files modified:
   trunk/boost/smart_ptr/detail/operator_bool.hpp | 11 ++++++-
   trunk/boost/smart_ptr/intrusive_ptr.hpp | 24 ++++++++++++++++
   trunk/boost/smart_ptr/scoped_array.hpp | 25 ++++++++++++++++
   trunk/boost/smart_ptr/scoped_ptr.hpp | 25 ++++++++++++++++
   trunk/boost/smart_ptr/shared_array.hpp | 24 ++++++++++++++++
   trunk/boost/smart_ptr/shared_ptr.hpp | 60 +++++++++++++++++++++++++++++++++++++++
   trunk/libs/smart_ptr/test/Jamfile.v2 | 2 +
   7 files changed, 168 insertions(+), 3 deletions(-)

Modified: trunk/boost/smart_ptr/detail/operator_bool.hpp
==============================================================================
--- trunk/boost/smart_ptr/detail/operator_bool.hpp (original)
+++ trunk/boost/smart_ptr/detail/operator_bool.hpp 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -1,12 +1,19 @@
 // This header intentionally has no include guards.
 //
-// Copyright (c) 2001-2009 Peter Dimov
+// Copyright (c) 2001-2009, 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
 
-#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
+#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )
+
+ explicit operator bool () const BOOST_NOEXCEPT
+ {
+ return px != 0;
+ }
+
+#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
 
     operator bool () const BOOST_NOEXCEPT
     {

Modified: trunk/boost/smart_ptr/intrusive_ptr.hpp
==============================================================================
--- trunk/boost/smart_ptr/intrusive_ptr.hpp (original)
+++ trunk/boost/smart_ptr/intrusive_ptr.hpp 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -218,6 +218,30 @@
 
 #endif
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( intrusive_ptr<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator==( std::nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( intrusive_ptr<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( std::nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+#endif
+
 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
 {
     return std::less<T *>()(a.get(), b.get());

Modified: trunk/boost/smart_ptr/scoped_array.hpp
==============================================================================
--- trunk/boost/smart_ptr/scoped_array.hpp (original)
+++ trunk/boost/smart_ptr/scoped_array.hpp 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -11,6 +11,7 @@
 // http://www.boost.org/libs/smart_ptr/scoped_array.htm
 //
 
+#include <boost/config.hpp>
 #include <boost/assert.hpp>
 #include <boost/checked_delete.hpp>
 #include <boost/config.hpp> // in case ptrdiff_t not in std
@@ -97,6 +98,30 @@
     }
 };
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( scoped_array<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator==( std::nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( scoped_array<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( std::nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+#endif
+
 template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_NOEXCEPT
 {
     a.swap(b);

Modified: trunk/boost/smart_ptr/scoped_ptr.hpp
==============================================================================
--- trunk/boost/smart_ptr/scoped_ptr.hpp (original)
+++ trunk/boost/smart_ptr/scoped_ptr.hpp 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -11,6 +11,7 @@
 // http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
 //
 
+#include <boost/config.hpp>
 #include <boost/assert.hpp>
 #include <boost/checked_delete.hpp>
 #include <boost/detail/workaround.hpp>
@@ -114,6 +115,30 @@
     }
 };
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( scoped_ptr<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator==( std::nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( scoped_ptr<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( std::nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+#endif
+
 template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
 {
     a.swap(b);

Modified: trunk/boost/smart_ptr/shared_array.hpp
==============================================================================
--- trunk/boost/smart_ptr/shared_array.hpp (original)
+++ trunk/boost/smart_ptr/shared_array.hpp 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -243,6 +243,30 @@
     return a.get() != b.get();
 }
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( shared_array<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator==( std::nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( shared_array<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( std::nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+#endif
+
 template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
 {
     return std::less<T*>()(a.get(), b.get());

Modified: trunk/boost/smart_ptr/shared_ptr.hpp
==============================================================================
--- trunk/boost/smart_ptr/shared_ptr.hpp (original)
+++ trunk/boost/smart_ptr/shared_ptr.hpp 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -41,7 +41,7 @@
 #include <algorithm> // for std::swap
 #include <functional> // for std::less
 #include <typeinfo> // for std::bad_cast
-#include <cstddef> // for std::size_t
+#include <cstddef> // for std::size_t, std::nullptr_t
 
 #if !defined(BOOST_NO_IOSTREAM)
 #if !defined(BOOST_NO_IOSFWD)
@@ -339,6 +339,14 @@
     {
     }
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ shared_ptr( std::nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws
+ {
+ }
+
+#endif
+
     template<class Y>
     explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
     {
@@ -356,6 +364,14 @@
         boost::detail::sp_deleter_construct( this, p );
     }
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ template<class D> shared_ptr( std::nullptr_t p, D d ): px( p ), pn( p, d )
+ {
+ }
+
+#endif
+
     // As above, but with allocator. A's copy constructor shall not throw.
 
     template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
@@ -363,6 +379,14 @@
         boost::detail::sp_deleter_construct( this, p );
     }
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ template<class D, class A> shared_ptr( std::nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
+ {
+ }
+
+#endif
+
 // generated copy constructor, destructor are fine...
 
 #if defined( BOOST_HAS_RVALUE_REFS )
@@ -579,6 +603,16 @@
 
 #endif
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+ shared_ptr & operator=( std::nullptr_t ) BOOST_NOEXCEPT // never throws
+ {
+ this_type().swap(*this);
+ return *this;
+ }
+
+#endif
+
     void reset() BOOST_NOEXCEPT // never throws in 1.30+
     {
         this_type().swap(*this);
@@ -711,6 +745,30 @@
 
 #endif
 
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( shared_ptr<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator==( std::nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( shared_ptr<T> const & p, std::nullptr_t ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( std::nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+ return p.get() != 0;
+}
+
+#endif
+
 template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
 {
     return a.owner_before( b );

Modified: trunk/libs/smart_ptr/test/Jamfile.v2
==============================================================================
--- trunk/libs/smart_ptr/test/Jamfile.v2 (original)
+++ trunk/libs/smart_ptr/test/Jamfile.v2 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -75,6 +75,8 @@
           [ run sp_convertible_test.cpp ]
           [ run sp_array_n_test.cpp ]
           [ run sp_array_cast_test.cpp ]
+ [ run sp_zero_compare_test.cpp ]
+ [ run sp_nullptr_test.cpp ]
 
           [ compile-fail array_fail_spa_sp_c.cpp ]
           [ compile-fail array_fail_sp_spa_c.cpp ]

Added: trunk/libs/smart_ptr/test/sp_nullptr_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/sp_nullptr_test.cpp 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -0,0 +1,140 @@
+//
+// sp_nullptr_test.cpp
+//
+// Copyright 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/detail/lightweight_test.hpp>
+#include <cstddef>
+#include <memory>
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+struct X
+{
+ static int instances;
+
+ X()
+ {
+ ++instances;
+ }
+
+ ~X()
+ {
+ --instances;
+ }
+
+private:
+
+ X( X const & );
+ X & operator=( X const & );
+};
+
+int X::instances = 0;
+
+void f( std::nullptr_t )
+{
+}
+
+int main()
+{
+ {
+ boost::shared_ptr<void> p( nullptr );
+
+ BOOST_TEST( p.get() == 0 );
+ BOOST_TEST( p.use_count() == 0 );
+
+ BOOST_TEST( p == nullptr );
+ BOOST_TEST( nullptr == p );
+ BOOST_TEST( !( p != nullptr ) );
+ BOOST_TEST( !( nullptr != p ) );
+ }
+
+ {
+ boost::shared_ptr<int> p( nullptr, f );
+
+ BOOST_TEST( p.get() == 0 );
+ BOOST_TEST( p.use_count() == 1 );
+
+ BOOST_TEST( p == nullptr );
+ BOOST_TEST( nullptr == p );
+ BOOST_TEST( !( p != nullptr ) );
+ BOOST_TEST( !( nullptr != p ) );
+ }
+
+ {
+ boost::shared_ptr<int> p( nullptr, f, std::allocator<int>() );
+
+ BOOST_TEST( p.get() == 0 );
+ BOOST_TEST( p.use_count() == 1 );
+
+ BOOST_TEST( p == nullptr );
+ BOOST_TEST( nullptr == p );
+ BOOST_TEST( !( p != nullptr ) );
+ BOOST_TEST( !( nullptr != p ) );
+ }
+
+ {
+ boost::shared_ptr<int> p( new int );
+
+ BOOST_TEST( p.get() != 0 );
+ BOOST_TEST( p.use_count() == 1 );
+
+ BOOST_TEST( p != nullptr );
+ BOOST_TEST( nullptr != p );
+ BOOST_TEST( !( p == nullptr ) );
+ BOOST_TEST( !( nullptr == p ) );
+
+ p = nullptr;
+
+ BOOST_TEST( p.get() == 0 );
+ BOOST_TEST( p.use_count() == 0 );
+
+ BOOST_TEST( p == nullptr );
+ BOOST_TEST( nullptr == p );
+ BOOST_TEST( !( p != nullptr ) );
+ BOOST_TEST( !( nullptr != p ) );
+ }
+
+ {
+ BOOST_TEST( X::instances == 0 );
+
+ boost::shared_ptr<X> p( new X );
+ BOOST_TEST( X::instances == 1 );
+
+ BOOST_TEST( p.get() != 0 );
+ BOOST_TEST( p.use_count() == 1 );
+
+ BOOST_TEST( p != nullptr );
+ BOOST_TEST( nullptr != p );
+ BOOST_TEST( !( p == nullptr ) );
+ BOOST_TEST( !( nullptr == p ) );
+
+ p = nullptr;
+ BOOST_TEST( X::instances == 0 );
+
+ BOOST_TEST( p.get() == 0 );
+ BOOST_TEST( p.use_count() == 0 );
+
+ BOOST_TEST( p == nullptr );
+ BOOST_TEST( nullptr == p );
+ BOOST_TEST( !( p != nullptr ) );
+ BOOST_TEST( !( nullptr != p ) );
+ }
+
+ return boost::report_errors();
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+
+#endif

Added: trunk/libs/smart_ptr/test/sp_zero_compare_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/sp_zero_compare_test.cpp 2012-12-07 19:51:59 EST (Fri, 07 Dec 2012)
@@ -0,0 +1,78 @@
+//
+// sp_zero_compare_test.cpp - == 0, != 0
+//
+// Copyright 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/scoped_ptr.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct W
+{
+};
+
+void intrusive_ptr_add_ref( W* )
+{
+}
+
+void intrusive_ptr_release( W* )
+{
+}
+
+int main()
+{
+ {
+ boost::scoped_ptr<int> p;
+
+ BOOST_TEST( p == 0 );
+ BOOST_TEST( 0 == p );
+ BOOST_TEST( !( p != 0 ) );
+ BOOST_TEST( !( 0 != p ) );
+ }
+
+ {
+ boost::scoped_array<int> p;
+
+ BOOST_TEST( p == 0 );
+ BOOST_TEST( 0 == p );
+ BOOST_TEST( !( p != 0 ) );
+ BOOST_TEST( !( 0 != p ) );
+ }
+
+ {
+ boost::shared_ptr<int> p;
+
+ BOOST_TEST( p == 0 );
+ BOOST_TEST( 0 == p );
+ BOOST_TEST( !( p != 0 ) );
+ BOOST_TEST( !( 0 != p ) );
+ }
+
+ {
+ boost::shared_array<int> p;
+
+ BOOST_TEST( p == 0 );
+ BOOST_TEST( 0 == p );
+ BOOST_TEST( !( p != 0 ) );
+ BOOST_TEST( !( 0 != p ) );
+ }
+
+ {
+ boost::intrusive_ptr<W> p;
+
+ BOOST_TEST( p == 0 );
+ BOOST_TEST( 0 == p );
+ BOOST_TEST( !( p != 0 ) );
+ BOOST_TEST( !( 0 != p ) );
+ }
+
+ return boost::report_errors();
+}


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