|
@@ -9,25 +9,16 @@
|
|
|
namespace boost {
|
|
|
namespace detail {
|
|
|
class controller {
|
|
|
-
|
|
|
public:
|
|
|
|
|
|
controller()
|
|
|
- : cnt(0)
|
|
|
- {}
|
|
|
-
|
|
|
- template <typename T>
|
|
|
- controller(T* ptr)
|
|
|
- : cnt(ptr?1:0)
|
|
|
+ : cnt(1)
|
|
|
{}
|
|
|
|
|
|
public:
|
|
|
|
|
|
template <typename T>
|
|
|
controller* decref(T* pt) {
|
|
|
- if (!pt) {
|
|
|
- return NULL;
|
|
|
- }
|
|
|
if (--cnt <= 0) {
|
|
|
delete this;
|
|
|
delete pt;
|
|
@@ -81,6 +72,10 @@ class shared_ptr
|
|
|
{
|
|
|
template <typename TT> friend class shared_ptr;
|
|
|
|
|
|
+ template<class TT, class U> friend shared_ptr<TT> static_pointer_cast (shared_ptr<U> ptr);
|
|
|
+ template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast (shared_ptr<U> ptr);
|
|
|
+ template<class TT, class U> friend shared_ptr<TT> const_pointer_cast (shared_ptr<U> ptr);
|
|
|
+
|
|
|
template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
|
|
template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
|
|
template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
|
@@ -94,38 +89,61 @@ public:
|
|
|
// provide a default constructor
|
|
|
shared_ptr()
|
|
|
: ptr()
|
|
|
- , ctr(new detail::controller())
|
|
|
+ , ctr(NULL)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
// construction from an existing object of type T
|
|
|
- explicit shared_ptr(T* _ptr)
|
|
|
- : ptr(_ptr)
|
|
|
- , ctr(new detail::controller(ptr))
|
|
|
+ explicit shared_ptr(T* ptr)
|
|
|
+ : ptr(ptr)
|
|
|
+ , ctr(ptr ? new detail::controller() : NULL)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ shared_ptr(const shared_ptr& r)
|
|
|
+ : ptr(r.ptr)
|
|
|
+ , ctr(r.ctr ? r.ctr->incref() : NULL)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
template <typename Y>
|
|
|
- shared_ptr(const shared_ptr<Y>& o,typename detail::is_convertible<T,Y>::result = detail::empty())
|
|
|
- : ptr(o.ptr)
|
|
|
- , ctr(o.ctr->incref())
|
|
|
+ shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
|
|
|
+ : ptr(r.ptr)
|
|
|
+ , ctr(r.ctr ? r.ctr->incref() : NULL)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
- shared_ptr& operator= (const shared_ptr& r) {
|
|
|
- if(r == *this) {
|
|
|
+ // automatic destruction of the wrapped object when all
|
|
|
+ // references are freed.
|
|
|
+ ~shared_ptr() {
|
|
|
+ if (ctr) {
|
|
|
+ ctr = ctr->decref(ptr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ shared_ptr& operator=(const shared_ptr& r) {
|
|
|
+ if (this == &r) {
|
|
|
return *this;
|
|
|
}
|
|
|
- ctr->decref(ptr);
|
|
|
- ctr = r.ctr->incref();
|
|
|
+ if (ctr) {
|
|
|
+ ctr->decref(ptr);
|
|
|
+ }
|
|
|
ptr = r.ptr;
|
|
|
+ ctr = ptr?r.ctr->incref():NULL;
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
- // automatic destruction of the wrapped object when all
|
|
|
- // references are freed.
|
|
|
- ~shared_ptr() {
|
|
|
- ctr = ctr->decref(ptr);
|
|
|
+ template <typename Y>
|
|
|
+ shared_ptr& operator=(const shared_ptr<Y>& r) {
|
|
|
+ if (this == &r) {
|
|
|
+ return *this;
|
|
|
+ }
|
|
|
+ if (ctr) {
|
|
|
+ ctr->decref(ptr);
|
|
|
+ }
|
|
|
+ ptr = r.ptr;
|
|
|
+ ctr = ptr?r.ctr->incref():NULL;
|
|
|
+ return *this;
|
|
|
}
|
|
|
|
|
|
// pointer access
|
|
@@ -133,12 +151,16 @@ public:
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
|
- inline T* operator-> () {
|
|
|
+ inline T* operator-> () const {
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
|
// standard semantics
|
|
|
- inline T* get() {
|
|
|
+ inline T* get() {
|
|
|
+ return ptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ inline const T* get() const {
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
@@ -155,11 +177,11 @@ public:
|
|
|
}
|
|
|
|
|
|
inline void reset (T* t = 0) {
|
|
|
- ctr = ctr->decref(ptr);
|
|
|
- ptr = t;
|
|
|
- if(ptr) {
|
|
|
- ctr = new detail::controller(ptr);
|
|
|
+ if (ctr) {
|
|
|
+ ctr->decref(ptr);
|
|
|
}
|
|
|
+ ptr = t;
|
|
|
+ ctr = ptr?new detail::controller():NULL;
|
|
|
}
|
|
|
|
|
|
void swap(shared_ptr & b) {
|
|
@@ -167,6 +189,16 @@ public:
|
|
|
std::swap(ctr, b.ctr);
|
|
|
}
|
|
|
|
|
|
+private:
|
|
|
+
|
|
|
+
|
|
|
+ // for use by the various xxx_pointer_cast helper templates
|
|
|
+ explicit shared_ptr(T* ptr, detail::controller* ctr)
|
|
|
+ : ptr(ptr)
|
|
|
+ , ctr(ctr->incref())
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
private:
|
|
|
|
|
|
// encapsulated object pointer
|
|
@@ -197,6 +229,26 @@ bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
|
|
|
}
|
|
|
|
|
|
|
|
|
+template<class T, class U>
|
|
|
+inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
|
|
|
+{
|
|
|
+ return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr);
|
|
|
+}
|
|
|
+
|
|
|
+template<class T, class U>
|
|
|
+inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr)
|
|
|
+{
|
|
|
+ return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr);
|
|
|
+}
|
|
|
+
|
|
|
+template<class T, class U>
|
|
|
+inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr)
|
|
|
+{
|
|
|
+ return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
} // end of namespace boost
|
|
|
|
|
|
#else
|