2 // helper code for dealing with tracking non-boost shared_ptr/weak_ptr
4 // Copyright Frank Mori Hess 2009.
5 // Distributed under the Boost Software License, Version
6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 // See http://www.boost.org/libs/signals2 for library home page.
11 #ifndef BOOST_SIGNALS2_FOREIGN_PTR_HPP
12 #define BOOST_SIGNALS2_FOREIGN_PTR_HPP
15 #include <boost/config.hpp>
16 #include <boost/assert.hpp>
17 #include <boost/scoped_ptr.hpp>
18 #include <boost/smart_ptr/bad_weak_ptr.hpp>
19 #include <boost/utility/swap.hpp>
21 #ifndef BOOST_NO_CXX11_SMART_PTR
27 template<typename T> class shared_ptr;
28 template<typename T> class weak_ptr;
32 template<typename WeakPtr> struct weak_ptr_traits
34 template<typename T> struct weak_ptr_traits<boost::weak_ptr<T> >
36 typedef boost::shared_ptr<T> shared_type;
38 #ifndef BOOST_NO_CXX11_SMART_PTR
39 template<typename T> struct weak_ptr_traits<std::weak_ptr<T> >
41 typedef std::shared_ptr<T> shared_type;
45 template<typename SharedPtr> struct shared_ptr_traits
48 template<typename T> struct shared_ptr_traits<boost::shared_ptr<T> >
50 typedef boost::weak_ptr<T> weak_type;
52 #ifndef BOOST_NO_CXX11_SMART_PTR
53 template<typename T> struct shared_ptr_traits<std::shared_ptr<T> >
55 typedef std::weak_ptr<T> weak_type;
61 struct foreign_shared_ptr_impl_base
63 virtual ~foreign_shared_ptr_impl_base() {}
64 virtual foreign_shared_ptr_impl_base * clone() const = 0;
67 template<typename FSP>
68 class foreign_shared_ptr_impl: public foreign_shared_ptr_impl_base
71 foreign_shared_ptr_impl(const FSP &p): _p(p)
73 virtual foreign_shared_ptr_impl * clone() const
75 return new foreign_shared_ptr_impl(*this);
81 class foreign_void_shared_ptr
84 foreign_void_shared_ptr():
87 foreign_void_shared_ptr(const foreign_void_shared_ptr &other):
90 template<typename FSP>
91 explicit foreign_void_shared_ptr(const FSP &fsp):
92 _p(new foreign_shared_ptr_impl<FSP>(fsp))
94 ~foreign_void_shared_ptr()
98 foreign_void_shared_ptr & operator=(const foreign_void_shared_ptr &other)
100 if(&other == this) return *this;
101 foreign_void_shared_ptr(other).swap(*this);
104 void swap(foreign_void_shared_ptr &other)
106 boost::swap(_p, other._p);
109 foreign_shared_ptr_impl_base *_p;
112 struct foreign_weak_ptr_impl_base
114 virtual ~foreign_weak_ptr_impl_base() {}
115 virtual foreign_void_shared_ptr lock() const = 0;
116 virtual bool expired() const = 0;
117 virtual foreign_weak_ptr_impl_base * clone() const = 0;
120 template<typename FWP>
121 class foreign_weak_ptr_impl: public foreign_weak_ptr_impl_base
124 foreign_weak_ptr_impl(const FWP &p): _p(p)
126 virtual foreign_void_shared_ptr lock() const
128 return foreign_void_shared_ptr(_p.lock());
130 virtual bool expired() const
134 virtual foreign_weak_ptr_impl * clone() const
136 return new foreign_weak_ptr_impl(*this);
142 class foreign_void_weak_ptr
145 foreign_void_weak_ptr()
147 foreign_void_weak_ptr(const foreign_void_weak_ptr &other):
148 _p(other._p->clone())
150 template<typename FWP>
151 explicit foreign_void_weak_ptr(const FWP &fwp):
152 _p(new foreign_weak_ptr_impl<FWP>(fwp))
154 foreign_void_weak_ptr & operator=(const foreign_void_weak_ptr &other)
156 if(&other == this) return *this;
157 foreign_void_weak_ptr(other).swap(*this);
160 void swap(foreign_void_weak_ptr &other)
162 boost::swap(_p, other._p);
164 foreign_void_shared_ptr lock() const
170 return _p->expired();
173 boost::scoped_ptr<foreign_weak_ptr_impl_base> _p;
175 } // namespace detail
177 } // namespace signals2
180 #endif // BOOST_SIGNALS2_FOREIGN_PTR_HPP