#ifndef INCLUDED_AI_BOOST_SHARED_ARRAY #define INCLUDED_AI_BOOST_SHARED_ARRAY #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED // ------------------------------ // Internal stub namespace boost { namespace array_detail { class controller { public: controller() : cnt(1) {} public: template <typename T> 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 <typename DEST, typename SRC> 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 <bool> struct enable_if {}; template <> struct enable_if<true> { typedef empty result; }; template <typename DEST, typename SRC> struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > { }; } // ------------------------------ // Small replacement for boost::shared_array, not threadsafe because no // atomic reference counter is in use. // ------------------------------ template <class T> class shared_array { template <typename TT> friend class shared_array; template<class TT> friend bool operator== (const shared_array<TT>& a, const shared_array<TT>& b); template<class TT> friend bool operator!= (const shared_array<TT>& a, const shared_array<TT>& b); template<class TT> friend bool operator< (const shared_array<TT>& a, const shared_array<TT>& b); public: typedef T element_type; public: // provide a default constructor shared_array() : ptr() , ctr(NULL) { } // construction from an existing object of type T explicit shared_array(T* ptr) : ptr(ptr) , ctr(ptr ? new array_detail::controller() : NULL) { } shared_array(const shared_array& r) : ptr(r.ptr) , ctr(r.ctr ? r.ctr->incref() : NULL) { } template <typename Y> shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::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_array() { if (ctr) { ctr = ctr->decref(ptr); } } shared_array& operator=(const shared_array& r) { if (this == &r) { return *this; } if (ctr) { ctr->decref(ptr); } ptr = r.ptr; ctr = ptr?r.ctr->incref():NULL; return *this; } template <typename Y> shared_array& operator=(const shared_array<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 inline operator T*() { return ptr; } inline T* operator-> () const { return ptr; } // standard semantics inline T* get() { return ptr; } T& operator[] (std::ptrdiff_t index) const { return ptr[index]; } 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 array_detail::controller():NULL; } void swap(shared_array & b) { std::swap(ptr, b.ptr); std::swap(ctr, b.ctr); } private: // encapsulated object pointer T* ptr; // control block array_detail::controller* ctr; }; template<class T> inline void swap(shared_array<T> & a, shared_array<T> & b) { a.swap(b); } template<class T> bool operator== (const shared_array<T>& a, const shared_array<T>& b) { return a.ptr == b.ptr; } template<class T> bool operator!= (const shared_array<T>& a, const shared_array<T>& b) { return a.ptr != b.ptr; } template<class T> bool operator< (const shared_array<T>& a, const shared_array<T>& b) { return a.ptr < b.ptr; } } // end of namespace boost #else # error "shared_array.h was already included" #endif #endif // INCLUDED_AI_BOOST_SHARED_ARRAY