00001 #ifndef BOOSTER_SMART_PTR_WEAK_PTR_HPP_INCLUDED
00002 #define BOOSTER_SMART_PTR_WEAK_PTR_HPP_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <memory>
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
00033 typedef weak_ptr<T> this_type;
00034
00035 public:
00036
00037 typedef T element_type;
00038
00039 weak_ptr(): px(0), pn()
00040 {
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
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)
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 )
00073 {
00074 }
00075
00076 template<class Y>
00077 weak_ptr & operator=(weak_ptr<Y> const & r)
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)
00086 {
00087 px = r.px;
00088 pn = r.pn;
00089 return *this;
00090 }
00091
00092 shared_ptr<T> lock() const
00093 {
00094 return shared_ptr<element_type>( *this, booster::detail::sp_nothrow_tag() );
00095 }
00096
00097 long use_count() const
00098 {
00099 return pn.use_count();
00100 }
00101
00102 bool expired() const
00103 {
00104 return pn.use_count() == 0;
00105 }
00106
00107 bool _empty() const
00108 {
00109 return pn.empty();
00110 }
00111
00112 void reset()
00113 {
00114 this_type().swap(*this);
00115 }
00116
00117 void swap(this_type & other)
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
00135
00136
00137 private:
00138
00139 template<class Y> friend class weak_ptr;
00140 template<class Y> friend class shared_ptr;
00141
00142 T * px;
00143 booster::detail::weak_count pn;
00144
00145 };
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 }
00158
00159 #ifdef BOOSTER_MSVC
00160 # pragma warning(pop)
00161 #endif
00162
00163 #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED