From 5a6cd1cf3ee66077dc14ca17a421f6869859197d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 15 Feb 2002 13:31:58 +0000 Subject: [PATCH] Added a default constructor to shared_count and shared_ptr for incomplete types (void). [SVN r12815] --- include/boost/detail/shared_count.hpp | 6 +++- include/boost/shared_ptr.hpp | 15 ++++++-- shared_ptr.htm | 50 +++++++++++++++++++++------ 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/include/boost/detail/shared_count.hpp b/include/boost/detail/shared_count.hpp index 2e0dc47..d513329 100644 --- a/include/boost/detail/shared_count.hpp +++ b/include/boost/detail/shared_count.hpp @@ -186,6 +186,10 @@ private: public: + shared_count(): pi_(new counted_base(1, 1)) + { + } + template shared_count(P p, D d): pi_(0) { try @@ -221,7 +225,7 @@ public: pi_->add_ref(); } - explicit shared_count(weak_count const & r); // throws bad_weak_to_shared_cast when r.use_count() == 0 + explicit shared_count(weak_count const & r); // throws use_count_is_zero when r.use_count() == 0 shared_count & operator= (shared_count const & r) // nothrow { diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp index bd0fcff..e2ddb94 100644 --- a/include/boost/shared_ptr.hpp +++ b/include/boost/shared_ptr.hpp @@ -81,7 +81,11 @@ public: typedef T element_type; - explicit shared_ptr(T * p = 0): px(p), pn(p, deleter()) + shared_ptr(): px(0), pn() + { + } + + explicit shared_ptr(T * p): px(p), pn(p, deleter()) // requires complete type { } @@ -157,9 +161,14 @@ public: #endif - void reset(T * p = 0) + void reset() { - BOOST_ASSERT(p == 0 || p != px); + this_type().swap(*this); + } + + void reset(T * p) // requires complete type + { + BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors this_type(p).swap(*this); } diff --git a/shared_ptr.htm b/shared_ptr.htm index be3b1c5..ae1c36d 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -40,6 +40,8 @@

Synopsis

namespace boost {
 
+  class use_count_is_zero: public std::exception;
+
   template<typename T> class weak_ptr;
 
   template<typename T> class shared_ptr {
@@ -47,20 +49,22 @@
     public:
       typedef T element_type;
 
-      explicit shared_ptr(T * p = 0);
+      shared_ptr ();
+      explicit shared_ptr (T * p); // requires complete type
       template<typename D> shared_ptr(T * p, D d);
       ~shared_ptr(); // never throws
 
       shared_ptr(shared_ptr const & r); // never throws
       template<typename Y> shared_ptr(shared_ptr<Y> const & r); // never throws
-      shared_ptr(weak_ptr const & r);
+      explicit shared_ptr(weak_ptr const & r);
       template<typename Y> shared_ptr(std::auto_ptr<Y> & r);
 
       shared_ptr & operator=(shared_ptr const & r); // never throws  
       template<typename Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
       template<typename Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
 
-      void reset(T * p = 0);
+      void reset ();
+      void reset (T * p); // requires complete type
       template<typename D> void reset(T * p, D d);
 
       T & operator*() const; // never throws
@@ -99,7 +103,18 @@
 			

Provides the type of the template parameter T.

constructors

-
explicit shared_ptr(T * p = 0);
+
shared_ptr();
+
+

Effects: Constructs a shared_ptr.

+

Postconditions: use count is 1; the stored + pointer is 0.

+

Throws: std::bad_alloc.

+

Exception safety: If an exception is thrown, the constructor has no + effect.

+

Notes: T need not be a complete type. See the smart pointer + common requirements.

+
+
explicit shared_ptr(T * p);

Requirements: The expression delete p must be well-formed and must not invoke undefined behavior. @@ -136,7 +151,7 @@ template<typename Y> shared_ptr(shared_ptr<Y> const & r); // nev increased by one.

Throws: nothing.

-
shared_ptr(weak_ptr const & r);
+
explicit shared_ptr(weak_ptr const & r);

Effects: Constructs a shared_ptr, as if by storing a copy of the pointer stored in r.

@@ -174,11 +189,26 @@ template<typename Y> shared_ptr & operator=(shared_ptr<Y> const template<typename Y> shared_ptr & operator=(std::auto_ptr<Y> & r);

Effects: Equivalent to shared_ptr(r).swap(*this).

+

Notes: The implementation is free to meet the effects (and the implied + guarantees) via different means, without creating a temporary. In particular, + in the example:

+
+shared_ptr<int> p(new int);
+shared_ptr<void> q(p);
+p = p;
+q = p;
+
+

both assignments may be no-ops.

reset

-
void reset(T * p = 0);
+
void reset();
+
+

Effects: Equivalent to shared_ptr().swap(*this).

+
+
void reset(T * p);

Effects: Equivalent to shared_ptr(p).swap(*this).

+

Notes: Note the implied requirement that T is a complete type.

template<typename D> void reset(T * p, D d);
@@ -312,8 +342,8 @@ template<typename Y> shared_ptr & operator=(std::auto_ptr<Y> &am shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r);

Requires: The expression - polymorphic_cast<T*>(r.get()) must be well-formed and - its behavior defined.

+ polymorphic_cast<T*>(r.get()) must be well-formed and + its behavior defined.

Returns: A shared_ptr<T> object that stores a copy of polymorphic_cast<T*>(r.get()) and shares ownership with r.

@@ -325,8 +355,8 @@ template<typename Y> shared_ptr & operator=(std::auto_ptr<Y> &am shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r); // never throws

Requires: The expression - polymorphic_downcast<T*>(r.get()) must be well-formed - and its behavior defined.

+ polymorphic_downcast<T*>(r.get()) must be well-formed + and its behavior defined.

Returns: A shared_ptr<T> object that stores a copy of polymorphic_downcast<T*>(r.get()) and shares ownership with r.