williamr@2: #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED williamr@2: #define BOOST_SHARED_ARRAY_HPP_INCLUDED williamr@2: williamr@2: // williamr@2: // shared_array.hpp 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 // for broken compiler workarounds williamr@2: williamr@2: #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) williamr@2: #include williamr@2: #else williamr@2: williamr@2: #include // TR1 cyclic inclusion fix williamr@2: williamr@2: #include williamr@2: #include williamr@2: 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: williamr@2: namespace boost williamr@2: { williamr@2: williamr@2: // williamr@2: // shared_array williamr@2: // williamr@2: // shared_array extends shared_ptr to arrays. williamr@2: // The array pointed to is deleted when the last shared_array pointing to it williamr@2: // is destroyed or reset. williamr@2: // williamr@2: williamr@2: template class shared_array williamr@2: { williamr@2: private: williamr@2: williamr@2: // Borland 5.5.1 specific workarounds williamr@2: typedef checked_array_deleter deleter; williamr@2: typedef shared_array this_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), pn(p, deleter()) williamr@2: { williamr@2: } williamr@2: williamr@2: // williamr@2: // Requirements: D's copy constructor must not throw williamr@2: // williamr@2: // shared_array will release p by calling d(p) williamr@2: // williamr@2: williamr@2: template shared_array(T * p, D d): px(p), pn(p, d) williamr@2: { williamr@2: } williamr@2: williamr@2: // generated copy constructor, assignment, destructor are fine williamr@2: williamr@2: void reset(T * p = 0) williamr@2: { williamr@2: BOOST_ASSERT(p == 0 || p != px); williamr@2: this_type(p).swap(*this); williamr@2: } williamr@2: williamr@2: template void reset(T * p, D d) williamr@2: { williamr@2: this_type(p, d).swap(*this); 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: T * get() const // never throws williamr@2: { williamr@2: return px; williamr@2: } williamr@2: williamr@2: // implicit conversion to "bool" williamr@2: williamr@2: #if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) williamr@2: williamr@2: operator bool () const williamr@2: { williamr@2: return px != 0; williamr@2: } williamr@2: williamr@2: #elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) williamr@2: typedef T * (this_type::*unspecified_bool_type)() const; williamr@2: williamr@2: operator unspecified_bool_type() const // never throws williamr@2: { williamr@2: return px == 0? 0: &this_type::get; williamr@2: } williamr@2: williamr@2: #else williamr@2: williamr@2: typedef T * this_type::*unspecified_bool_type; williamr@2: williamr@2: operator unspecified_bool_type() const // never throws williamr@2: { williamr@2: return px == 0? 0: &this_type::px; williamr@2: } williamr@2: williamr@2: #endif williamr@2: williamr@2: bool operator! () const // never throws williamr@2: { williamr@2: return px == 0; williamr@2: } williamr@2: williamr@2: bool unique() const // never throws williamr@2: { williamr@2: return pn.unique(); williamr@2: } williamr@2: williamr@2: long use_count() const // never throws williamr@2: { williamr@2: return pn.use_count(); williamr@2: } williamr@2: williamr@2: void swap(shared_array & other) // never throws williamr@2: { williamr@2: std::swap(px, other.px); williamr@2: pn.swap(other.pn); williamr@2: } williamr@2: williamr@2: private: williamr@2: williamr@2: T * px; // contained pointer williamr@2: detail::shared_count pn; // reference counter williamr@2: williamr@2: }; // shared_array williamr@2: williamr@2: template inline bool operator==(shared_array const & a, shared_array const & b) // never throws 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) // never throws 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) // never throws 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) // never throws williamr@2: { williamr@2: a.swap(b); williamr@2: } williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: #endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) williamr@2: williamr@2: #endif // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED