nuclear@0: nuclear@0: #ifndef INCLUDED_AI_BOOST_SHARED_ARRAY nuclear@0: #define INCLUDED_AI_BOOST_SHARED_ARRAY nuclear@0: nuclear@0: #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED nuclear@0: nuclear@0: // ------------------------------ nuclear@0: // Internal stub nuclear@0: namespace boost { nuclear@0: namespace array_detail { nuclear@0: class controller { nuclear@0: public: nuclear@0: nuclear@0: controller() nuclear@0: : cnt(1) nuclear@0: {} nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: template nuclear@0: controller* decref(T* pt) { nuclear@0: if (--cnt <= 0) { nuclear@0: delete this; nuclear@0: delete[] pt; nuclear@0: } nuclear@0: return NULL; nuclear@0: } nuclear@0: nuclear@0: controller* incref() { nuclear@0: ++cnt; nuclear@0: return this; nuclear@0: } nuclear@0: nuclear@0: long get() const { nuclear@0: return cnt; nuclear@0: } nuclear@0: nuclear@0: private: nuclear@0: long cnt; nuclear@0: }; nuclear@0: nuclear@0: struct empty {}; nuclear@0: nuclear@0: template nuclear@0: struct is_convertible_stub { nuclear@0: nuclear@0: struct yes {char s[1];}; nuclear@0: struct no {char s[2];}; nuclear@0: nuclear@0: static yes foo(DEST*); nuclear@0: static no foo(...); nuclear@0: nuclear@0: enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)}; nuclear@0: }; nuclear@0: nuclear@0: template struct enable_if {}; nuclear@0: template <> struct enable_if { nuclear@0: typedef empty result; nuclear@0: }; nuclear@0: nuclear@0: template nuclear@0: struct is_convertible : public enable_if::result > { nuclear@0: }; nuclear@0: } nuclear@0: nuclear@0: // ------------------------------ nuclear@0: // Small replacement for boost::shared_array, not threadsafe because no nuclear@0: // atomic reference counter is in use. nuclear@0: // ------------------------------ nuclear@0: template nuclear@0: class shared_array nuclear@0: { nuclear@0: template friend class shared_array; nuclear@0: nuclear@0: template friend bool operator== (const shared_array& a, const shared_array& b); nuclear@0: template friend bool operator!= (const shared_array& a, const shared_array& b); nuclear@0: template friend bool operator< (const shared_array& a, const shared_array& b); nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: typedef T element_type; nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: // provide a default constructor nuclear@0: shared_array() nuclear@0: : ptr() nuclear@0: , ctr(NULL) nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: // construction from an existing object of type T nuclear@0: explicit shared_array(T* ptr) nuclear@0: : ptr(ptr) nuclear@0: , ctr(ptr ? new array_detail::controller() : NULL) nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: shared_array(const shared_array& r) nuclear@0: : ptr(r.ptr) nuclear@0: , ctr(r.ctr ? r.ctr->incref() : NULL) nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: template nuclear@0: shared_array(const shared_array& r,typename detail::is_convertible::result = detail::empty()) nuclear@0: : ptr(r.ptr) nuclear@0: , ctr(r.ctr ? r.ctr->incref() : NULL) nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: // automatic destruction of the wrapped object when all nuclear@0: // references are freed. nuclear@0: ~shared_array() { nuclear@0: if (ctr) { nuclear@0: ctr = ctr->decref(ptr); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: shared_array& operator=(const shared_array& r) { nuclear@0: if (this == &r) { nuclear@0: return *this; nuclear@0: } nuclear@0: if (ctr) { nuclear@0: ctr->decref(ptr); nuclear@0: } nuclear@0: ptr = r.ptr; nuclear@0: ctr = ptr?r.ctr->incref():NULL; nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: template nuclear@0: shared_array& operator=(const shared_array& r) { nuclear@0: if (this == &r) { nuclear@0: return *this; nuclear@0: } nuclear@0: if (ctr) { nuclear@0: ctr->decref(ptr); nuclear@0: } nuclear@0: ptr = r.ptr; nuclear@0: ctr = ptr?r.ctr->incref():NULL; nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: // pointer access nuclear@0: inline operator T*() { nuclear@0: return ptr; nuclear@0: } nuclear@0: nuclear@0: inline T* operator-> () const { nuclear@0: return ptr; nuclear@0: } nuclear@0: nuclear@0: // standard semantics nuclear@0: inline T* get() { nuclear@0: return ptr; nuclear@0: } nuclear@0: nuclear@0: T& operator[] (std::ptrdiff_t index) const { nuclear@0: return ptr[index]; nuclear@0: } nuclear@0: nuclear@0: inline const T* get() const { nuclear@0: return ptr; nuclear@0: } nuclear@0: nuclear@0: inline operator bool () const { nuclear@0: return ptr != NULL; nuclear@0: } nuclear@0: nuclear@0: inline bool unique() const { nuclear@0: return use_count() == 1; nuclear@0: } nuclear@0: nuclear@0: inline long use_count() const { nuclear@0: return ctr->get(); nuclear@0: } nuclear@0: nuclear@0: inline void reset (T* t = 0) { nuclear@0: if (ctr) { nuclear@0: ctr->decref(ptr); nuclear@0: } nuclear@0: ptr = t; nuclear@0: ctr = ptr?new array_detail::controller():NULL; nuclear@0: } nuclear@0: nuclear@0: void swap(shared_array & b) { nuclear@0: std::swap(ptr, b.ptr); nuclear@0: std::swap(ctr, b.ctr); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: private: nuclear@0: nuclear@0: // encapsulated object pointer nuclear@0: T* ptr; nuclear@0: nuclear@0: // control block nuclear@0: array_detail::controller* ctr; nuclear@0: }; nuclear@0: nuclear@0: template nuclear@0: inline void swap(shared_array & a, shared_array & b) nuclear@0: { nuclear@0: a.swap(b); nuclear@0: } nuclear@0: nuclear@0: template nuclear@0: bool operator== (const shared_array& a, const shared_array& b) { nuclear@0: return a.ptr == b.ptr; nuclear@0: } nuclear@0: template nuclear@0: bool operator!= (const shared_array& a, const shared_array& b) { nuclear@0: return a.ptr != b.ptr; nuclear@0: } nuclear@0: nuclear@0: template nuclear@0: bool operator< (const shared_array& a, const shared_array& b) { nuclear@0: return a.ptr < b.ptr; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: } // end of namespace boost nuclear@0: nuclear@0: #else nuclear@0: # error "shared_array.h was already included" nuclear@0: #endif nuclear@0: #endif // INCLUDED_AI_BOOST_SHARED_ARRAY