williamr@2: #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED williamr@2: #define BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED williamr@2: williamr@2: // williamr@2: // detail/shared_array_nmt.hpp - shared_array.hpp without member templates williamr@2: // williamr@2: // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. williamr@2: // Copyright (c) 2001, 2002 Peter Dimov williamr@2: // williamr@2: // Distributed under the Boost Software License, Version 1.0. (See williamr@2: // accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: // williamr@2: // See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation. williamr@2: // williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: #include // for std::ptrdiff_t williamr@2: #include // for std::swap williamr@2: #include // for std::less williamr@2: #include // for std::bad_alloc williamr@2: williamr@2: namespace boost williamr@2: { williamr@2: williamr@2: template class shared_array williamr@2: { williamr@2: private: williamr@2: williamr@2: typedef detail::atomic_count count_type; williamr@2: williamr@2: public: williamr@2: williamr@2: typedef T element_type; williamr@2: williamr@2: explicit shared_array(T * p = 0): px(p) williamr@2: { williamr@2: #ifndef BOOST_NO_EXCEPTIONS williamr@2: williamr@2: try // prevent leak if new throws williamr@2: { williamr@2: pn = new count_type(1); williamr@2: } williamr@2: catch(...) williamr@2: { williamr@2: boost::checked_array_delete(p); williamr@2: throw; williamr@2: } williamr@2: williamr@2: #else williamr@2: williamr@2: pn = new count_type(1); williamr@2: williamr@2: if(pn == 0) williamr@2: { williamr@2: boost::checked_array_delete(p); williamr@2: boost::throw_exception(std::bad_alloc()); williamr@2: } williamr@2: williamr@2: #endif williamr@2: } williamr@2: williamr@2: ~shared_array() williamr@2: { williamr@2: if(--*pn == 0) williamr@2: { williamr@2: boost::checked_array_delete(px); williamr@2: delete pn; williamr@2: } williamr@2: } williamr@2: williamr@2: shared_array(shared_array const & r) : px(r.px) // never throws williamr@2: { williamr@2: pn = r.pn; williamr@2: ++*pn; williamr@2: } williamr@2: williamr@2: shared_array & operator=(shared_array const & r) williamr@2: { williamr@2: shared_array(r).swap(*this); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: void reset(T * p = 0) williamr@2: { williamr@2: BOOST_ASSERT(p == 0 || p != px); williamr@2: shared_array(p).swap(*this); williamr@2: } williamr@2: williamr@2: T * get() const // never throws williamr@2: { williamr@2: return px; williamr@2: } williamr@2: williamr@2: T & operator[](std::ptrdiff_t i) const // never throws williamr@2: { williamr@2: BOOST_ASSERT(px != 0); williamr@2: BOOST_ASSERT(i >= 0); williamr@2: return px[i]; williamr@2: } williamr@2: williamr@2: long use_count() const // never throws williamr@2: { williamr@2: return *pn; williamr@2: } williamr@2: williamr@2: bool unique() const // never throws williamr@2: { williamr@2: return *pn == 1; williamr@2: } williamr@2: williamr@2: void swap(shared_array & other) // never throws williamr@2: { williamr@2: std::swap(px, other.px); williamr@2: std::swap(pn, other.pn); williamr@2: } williamr@2: williamr@2: private: williamr@2: williamr@2: T * px; // contained pointer williamr@2: count_type * pn; // ptr to reference counter williamr@2: williamr@2: }; // shared_array williamr@2: williamr@2: template inline bool operator==(shared_array const & a, shared_array const & b) williamr@2: { williamr@2: return a.get() == b.get(); williamr@2: } williamr@2: williamr@2: template inline bool operator!=(shared_array const & a, shared_array const & b) williamr@2: { williamr@2: return a.get() != b.get(); williamr@2: } williamr@2: williamr@2: template inline bool operator<(shared_array const & a, shared_array const & b) williamr@2: { williamr@2: return std::less()(a.get(), b.get()); williamr@2: } williamr@2: williamr@2: template void swap(shared_array & a, shared_array & b) williamr@2: { williamr@2: a.swap(b); williamr@2: } williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: #endif // #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED