#ifndef INCLUDED_AI_BOOST_SHARED_PTR #define INCLUDED_AI_BOOST_SHARED_PTR #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED // ------------------------------ // Internal stub namespace boost { namespace detail { class controller { public: controller() : cnt(1) {} public: template controller* decref(T* pt) { if (--cnt <= 0) { delete this; delete pt; } return NULL; } controller* incref() { ++cnt; return this; } long get() const { return cnt; } private: long cnt; }; struct empty {}; template struct is_convertible_stub { struct yes {char s[1];}; struct no {char s[2];}; static yes foo(DEST*); static no foo(...); enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)}; }; template struct enable_if {}; template <> struct enable_if { typedef empty result; }; template struct is_convertible : public enable_if::result > { }; } // ------------------------------ // Small replacement for boost::shared_ptr, not threadsafe because no // atomic reference counter is in use. // ------------------------------ template class shared_ptr { template friend class shared_ptr; template friend shared_ptr static_pointer_cast (shared_ptr ptr); template friend shared_ptr dynamic_pointer_cast (shared_ptr ptr); template friend shared_ptr const_pointer_cast (shared_ptr ptr); template friend bool operator== (const shared_ptr& a, const shared_ptr& b); template friend bool operator!= (const shared_ptr& a, const shared_ptr& b); template friend bool operator< (const shared_ptr& a, const shared_ptr& b); public: typedef T element_type; public: // provide a default constructor shared_ptr() : ptr() , ctr(NULL) { } // construction from an existing object of type T 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 shared_ptr(const shared_ptr& r,typename detail::is_convertible::result = detail::empty()) : ptr(r.ptr) , ctr(r.ctr ? r.ctr->incref() : NULL) { } // 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; } if (ctr) { ctr->decref(ptr); } ptr = r.ptr; ctr = ptr?r.ctr->incref():NULL; return *this; } template shared_ptr& operator=(const shared_ptr& r) { if (this == &r) { return *this; } if (ctr) { ctr->decref(ptr); } ptr = r.ptr; ctr = ptr?r.ctr->incref():NULL; return *this; } // pointer access inline operator T*() { return ptr; } inline T* operator-> () const { return ptr; } // standard semantics inline T* get() { return ptr; } inline const T* get() const { return ptr; } inline operator bool () const { return ptr != NULL; } inline bool unique() const { return use_count() == 1; } inline long use_count() const { return ctr->get(); } inline void reset (T* t = 0) { if (ctr) { ctr->decref(ptr); } ptr = t; ctr = ptr?new detail::controller():NULL; } void swap(shared_ptr & b) { std::swap(ptr, b.ptr); 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 T* ptr; // control block detail::controller* ctr; }; template inline void swap(shared_ptr & a, shared_ptr & b) { a.swap(b); } template bool operator== (const shared_ptr& a, const shared_ptr& b) { return a.ptr == b.ptr; } template bool operator!= (const shared_ptr& a, const shared_ptr& b) { return a.ptr != b.ptr; } template bool operator< (const shared_ptr& a, const shared_ptr& b) { return a.ptr < b.ptr; } template inline shared_ptr static_pointer_cast( shared_ptr ptr) { return shared_ptr(static_cast(ptr.ptr),ptr.ctr); } template inline shared_ptr dynamic_pointer_cast( shared_ptr ptr) { return shared_ptr(dynamic_cast(ptr.ptr),ptr.ctr); } template inline shared_ptr const_pointer_cast( shared_ptr ptr) { return shared_ptr(const_cast(ptr.ptr),ptr.ctr); } } // end of namespace boost #else # error "shared_ptr.h was already included" #endif #endif // INCLUDED_AI_BOOST_SCOPED_PTR