CppCMS
|
00001 #ifndef BOOSTER_SMART_PTR_WEAK_PTR_HPP_INCLUDED 00002 #define BOOSTER_SMART_PTR_WEAK_PTR_HPP_INCLUDED 00003 00004 // 00005 // weak_ptr.hpp 00006 // 00007 // Copyright (c) 2001, 2002, 2003 Peter Dimov 00008 // 00009 // Distributed under the Boost Software License, Version 1.0. (See 00010 // accompanying file LICENSE_1_0.txt or copy at 00011 // http://www.boost.org/LICENSE_1_0.txt) 00012 // 00013 // See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation. 00014 // 00015 00016 #include <memory> // boost.TR1 include order fix 00017 #include <booster/smart_ptr/shared_count.h> 00018 #include <booster/shared_ptr.h> 00019 00020 #ifdef BOOSTER_MSVC // moved here to work around VC++ compiler crash 00021 # pragma warning(push) 00022 # pragma warning(disable:4284) // odd return type for operator-> 00023 #endif 00024 00025 namespace booster 00026 { 00027 00028 template<class T> class weak_ptr 00029 { 00030 private: 00031 00032 // Borland 5.5.1 specific workarounds 00033 typedef weak_ptr<T> this_type; 00034 00035 public: 00036 00037 typedef T element_type; 00038 00039 weak_ptr(): px(0), pn() // never throws in 1.30+ 00040 { 00041 } 00042 00043 // generated copy constructor, assignment, destructor are fine 00044 00045 00046 // 00047 // The "obvious" converting constructor implementation: 00048 // 00049 // template<class Y> 00050 // weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws 00051 // { 00052 // } 00053 // 00054 // has a serious problem. 00055 // 00056 // r.px may already have been invalidated. The px(r.px) 00057 // conversion may require access to *r.px (virtual inheritance). 00058 // 00059 // It is not possible to avoid spurious access violations since 00060 // in multithreaded programs r.px may be invalidated at any point. 00061 // 00062 00063 template<class Y> 00064 weak_ptr( weak_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) 00065 : px(r.lock().get()), pn(r.pn) // never throws 00066 { 00067 } 00068 00069 00070 template<class Y> 00071 weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) 00072 : px( r.px ), pn( r.pn ) // never throws 00073 { 00074 } 00075 00076 template<class Y> 00077 weak_ptr & operator=(weak_ptr<Y> const & r) // never throws 00078 { 00079 px = r.lock().get(); 00080 pn = r.pn; 00081 return *this; 00082 } 00083 00084 template<class Y> 00085 weak_ptr & operator=(shared_ptr<Y> const & r) // never throws 00086 { 00087 px = r.px; 00088 pn = r.pn; 00089 return *this; 00090 } 00091 00092 shared_ptr<T> lock() const // never throws 00093 { 00094 return shared_ptr<element_type>( *this, booster::detail::sp_nothrow_tag() ); 00095 } 00096 00097 long use_count() const // never throws 00098 { 00099 return pn.use_count(); 00100 } 00101 00102 bool expired() const // never throws 00103 { 00104 return pn.use_count() == 0; 00105 } 00106 00107 bool _empty() const // extension, not in std::weak_ptr 00108 { 00109 return pn.empty(); 00110 } 00111 00112 void reset() // never throws in 1.30+ 00113 { 00114 this_type().swap(*this); 00115 } 00116 00117 void swap(this_type & other) // never throws 00118 { 00119 std::swap(px, other.px); 00120 pn.swap(other.pn); 00121 } 00122 00123 void _internal_assign(T * px2, booster::detail::shared_count const & pn2) 00124 { 00125 px = px2; 00126 pn = pn2; 00127 } 00128 00129 template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const 00130 { 00131 return pn < rhs.pn; 00132 } 00133 00134 // Tasteless as this may seem, making all members public allows member templates 00135 // to work in the absence of member template friends. (Matthew Langston) 00136 00137 private: 00138 00139 template<class Y> friend class weak_ptr; 00140 template<class Y> friend class shared_ptr; 00141 00142 T * px; // contained pointer 00143 booster::detail::weak_count pn; // reference counter 00144 00145 }; // weak_ptr 00146 00147 template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) 00148 { 00149 return a._internal_less(b); 00150 } 00151 00152 template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) 00153 { 00154 a.swap(b); 00155 } 00156 00157 } // namespace boost 00158 00159 #ifdef BOOSTER_MSVC 00160 # pragma warning(pop) 00161 #endif 00162 00163 #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED