00001 #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED 00002 #define BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED 00003 00004 // 00005 // detail/shared_array_nmt.hpp - shared_array.hpp without member templates 00006 // 00007 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. 00008 // Copyright (c) 2001, 2002 Peter Dimov 00009 // 00010 // Distributed under the Boost Software License, Version 1.0. (See 00011 // accompanying file LICENSE_1_0.txt or copy at 00012 // http://www.boost.org/LICENSE_1_0.txt) 00013 // 00014 // See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation. 00015 // 00016 00017 #include <sysc/packages/boost/assert.hpp> 00018 #include <sysc/packages/boost/checked_delete.hpp> 00019 #include <sysc/packages/boost/throw_exception.hpp> 00020 #include <sysc/packages/boost/detail/atomic_count.hpp> 00021 00022 #include <cstddef> // for std::ptrdiff_t 00023 #include <algorithm> // for std::swap 00024 #include <functional> // for std::less 00025 #include <new> // for std::bad_alloc 00026 00027 namespace boost 00028 { 00029 00030 template<class T> class shared_array 00031 { 00032 private: 00033 00034 typedef detail::atomic_count count_type; 00035 00036 public: 00037 00038 typedef T element_type; 00039 00040 explicit shared_array(T * p = 0): px(p) 00041 { 00042 #ifndef BOOST_NO_EXCEPTIONS 00043 00044 try // prevent leak if new throws 00045 { 00046 pn = new count_type(1); 00047 } 00048 catch(...) 00049 { 00050 boost::checked_array_delete(p); 00051 throw; 00052 } 00053 00054 #else 00055 00056 pn = new count_type(1); 00057 00058 if(pn == 0) 00059 { 00060 boost::checked_array_delete(p); 00061 boost::throw_exception(std::bad_alloc()); 00062 } 00063 00064 #endif 00065 } 00066 00067 ~shared_array() 00068 { 00069 if(--*pn == 0) 00070 { 00071 boost::checked_array_delete(px); 00072 delete pn; 00073 } 00074 } 00075 00076 shared_array(shared_array const & r) : px(r.px) // never throws 00077 { 00078 pn = r.pn; 00079 ++*pn; 00080 } 00081 00082 shared_array & operator=(shared_array const & r) 00083 { 00084 shared_array(r).swap(*this); 00085 return *this; 00086 } 00087 00088 void reset(T * p = 0) 00089 { 00090 BOOST_ASSERT(p == 0 || p != px); 00091 shared_array(p).swap(*this); 00092 } 00093 00094 T * get() const // never throws 00095 { 00096 return px; 00097 } 00098 00099 T & operator[](std::ptrdiff_t i) const // never throws 00100 { 00101 BOOST_ASSERT(px != 0); 00102 BOOST_ASSERT(i >= 0); 00103 return px[i]; 00104 } 00105 00106 long use_count() const // never throws 00107 { 00108 return *pn; 00109 } 00110 00111 bool unique() const // never throws 00112 { 00113 return *pn == 1; 00114 } 00115 00116 void swap(shared_array<T> & other) // never throws 00117 { 00118 std::swap(px, other.px); 00119 std::swap(pn, other.pn); 00120 } 00121 00122 private: 00123 00124 T * px; // contained pointer 00125 count_type * pn; // ptr to reference counter 00126 00127 }; // shared_array 00128 00129 template<class T, class U> inline bool operator==(shared_array<T> const & a, shared_array<U> const & b) 00130 { 00131 return a.get() == b.get(); 00132 } 00133 00134 template<class T, class U> inline bool operator!=(shared_array<T> const & a, shared_array<U> const & b) 00135 { 00136 return a.get() != b.get(); 00137 } 00138 00139 template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) 00140 { 00141 return std::less<T*>()(a.get(), b.get()); 00142 } 00143 00144 template<class T> void swap(shared_array<T> & a, shared_array<T> & b) 00145 { 00146 a.swap(b); 00147 } 00148 00149 } // namespace boost 00150 00151 #endif // #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
1.5.5