1 #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
2 #define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
7 // Copyright (c) 2001, 2002, 2003 Peter Dimov
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
13 // See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
16 #include <memory> // boost.TR1 include order fix
17 #include <boost/smart_ptr/detail/shared_count.hpp>
18 #include <boost/smart_ptr/shared_ptr.hpp>
23 template<class T> class weak_ptr
27 // Borland 5.5.1 specific workarounds
28 typedef weak_ptr<T> this_type;
32 typedef typename boost::detail::sp_element< T >::type element_type;
34 weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+
38 // generated copy constructor, assignment, destructor are fine...
40 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
42 // ... except in C++0x, move disables the implicit copy
44 weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
48 weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT
58 // The "obvious" converting constructor implementation:
61 // weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
65 // has a serious problem.
67 // r.px may already have been invalidated. The px(r.px)
68 // conversion may require access to *r.px (virtual inheritance).
70 // It is not possible to avoid spurious access violations since
71 // in multithreaded programs r.px may be invalidated at any point.
75 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
77 weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
81 weak_ptr( weak_ptr<Y> const & r )
84 BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn)
86 boost::detail::sp_assert_convertible< Y, T >();
89 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
92 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
94 weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
98 weak_ptr( weak_ptr<Y> && r )
101 BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
103 boost::detail::sp_assert_convertible< Y, T >();
107 // for better efficiency in the T == Y case
108 weak_ptr( weak_ptr && r )
109 BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
114 // for better efficiency in the T == Y case
115 weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
117 this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
125 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
127 weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
131 weak_ptr( shared_ptr<Y> const & r )
134 BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
136 boost::detail::sp_assert_convertible< Y, T >();
139 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
142 weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT
144 boost::detail::sp_assert_convertible< Y, T >();
152 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
155 weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
157 this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
164 weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT
166 boost::detail::sp_assert_convertible< Y, T >();
176 shared_ptr<T> lock() const BOOST_NOEXCEPT
178 return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
181 long use_count() const BOOST_NOEXCEPT
183 return pn.use_count();
186 bool expired() const BOOST_NOEXCEPT
188 return pn.use_count() == 0;
191 bool _empty() const // extension, not in std::weak_ptr
196 void reset() BOOST_NOEXCEPT // never throws in 1.30+
198 this_type().swap(*this);
201 void swap(this_type & other) BOOST_NOEXCEPT
203 std::swap(px, other.px);
208 void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
214 template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
219 template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
224 // Tasteless as this may seem, making all members public allows member templates
225 // to work in the absence of member template friends. (Matthew Langston)
227 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
231 template<class Y> friend class weak_ptr;
232 template<class Y> friend class shared_ptr;
236 element_type * px; // contained pointer
237 boost::detail::weak_count pn; // reference counter
241 template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_NOEXCEPT
243 return a.owner_before( b );
246 template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_NOEXCEPT
253 #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED