| |
| // helper code for dealing with tracking non-boost shared_ptr/weak_ptr |
| |
| // Copyright Frank Mori Hess 2009. |
| // Distributed under the Boost Software License, Version |
| // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| |
| // See http://www.boost.org/libs/signals2 for library home page. |
| |
| #ifndef BOOST_SIGNALS2_FOREIGN_PTR_HPP |
| #define BOOST_SIGNALS2_FOREIGN_PTR_HPP |
| |
| #include <algorithm> |
| #include <boost/assert.hpp> |
| #include <boost/scoped_ptr.hpp> |
| #include <boost/smart_ptr/bad_weak_ptr.hpp> |
| #include <boost/utility/swap.hpp> |
| |
| namespace std |
| { |
| template<typename T> class shared_ptr; |
| template<typename T> class weak_ptr; |
| } |
| |
| namespace boost |
| { |
| template<typename T> class shared_ptr; |
| template<typename T> class weak_ptr; |
| |
| namespace signals2 |
| { |
| template<typename WeakPtr> struct weak_ptr_traits |
| {}; |
| template<typename T> struct weak_ptr_traits<boost::weak_ptr<T> > |
| { |
| typedef boost::shared_ptr<T> shared_type; |
| }; |
| template<typename T> struct weak_ptr_traits<std::weak_ptr<T> > |
| { |
| typedef std::shared_ptr<T> shared_type; |
| }; |
| |
| template<typename SharedPtr> struct shared_ptr_traits |
| {}; |
| |
| template<typename T> struct shared_ptr_traits<boost::shared_ptr<T> > |
| { |
| typedef boost::weak_ptr<T> weak_type; |
| }; |
| template<typename T> struct shared_ptr_traits<std::shared_ptr<T> > |
| { |
| typedef std::weak_ptr<T> weak_type; |
| }; |
| |
| namespace detail |
| { |
| struct foreign_shared_ptr_impl_base |
| { |
| virtual ~foreign_shared_ptr_impl_base() {} |
| virtual void* get() const = 0; |
| virtual foreign_shared_ptr_impl_base * clone() const = 0; |
| }; |
| |
| template<typename FSP> |
| class foreign_shared_ptr_impl: public foreign_shared_ptr_impl_base |
| { |
| public: |
| foreign_shared_ptr_impl(const FSP &p): _p(p) |
| {} |
| virtual void * get() const |
| { |
| return _p.get(); |
| } |
| virtual foreign_shared_ptr_impl * clone() const |
| { |
| return new foreign_shared_ptr_impl(*this); |
| } |
| private: |
| FSP _p; |
| }; |
| |
| class foreign_void_shared_ptr |
| { |
| public: |
| foreign_void_shared_ptr(): |
| _p(0) |
| {} |
| foreign_void_shared_ptr(const foreign_void_shared_ptr &other): |
| _p(other._p->clone()) |
| {} |
| template<typename FSP> |
| explicit foreign_void_shared_ptr(const FSP &fsp): |
| _p(new foreign_shared_ptr_impl<FSP>(fsp)) |
| {} |
| ~foreign_void_shared_ptr() |
| { |
| delete _p; |
| } |
| foreign_void_shared_ptr & operator=(const foreign_void_shared_ptr &other) |
| { |
| if(&other == this) return *this; |
| foreign_void_shared_ptr(other).swap(*this); |
| return *this; |
| } |
| void swap(foreign_void_shared_ptr &other) |
| { |
| boost::swap(_p, other._p); |
| } |
| private: |
| foreign_shared_ptr_impl_base *_p; |
| }; |
| |
| struct foreign_weak_ptr_impl_base |
| { |
| virtual ~foreign_weak_ptr_impl_base() {} |
| virtual foreign_void_shared_ptr lock() const = 0; |
| virtual bool expired() const = 0; |
| virtual foreign_weak_ptr_impl_base * clone() const = 0; |
| }; |
| |
| template<typename FWP> |
| class foreign_weak_ptr_impl: public foreign_weak_ptr_impl_base |
| { |
| public: |
| foreign_weak_ptr_impl(const FWP &p): _p(p) |
| {} |
| virtual foreign_void_shared_ptr lock() const |
| { |
| return foreign_void_shared_ptr(_p.lock()); |
| } |
| virtual bool expired() const |
| { |
| return _p.expired(); |
| } |
| virtual foreign_weak_ptr_impl * clone() const |
| { |
| return new foreign_weak_ptr_impl(*this); |
| } |
| private: |
| FWP _p; |
| }; |
| |
| class foreign_void_weak_ptr |
| { |
| public: |
| foreign_void_weak_ptr() |
| {} |
| foreign_void_weak_ptr(const foreign_void_weak_ptr &other): |
| _p(other._p->clone()) |
| {} |
| template<typename FWP> |
| explicit foreign_void_weak_ptr(const FWP &fwp): |
| _p(new foreign_weak_ptr_impl<FWP>(fwp)) |
| {} |
| foreign_void_weak_ptr & operator=(const foreign_void_weak_ptr &other) |
| { |
| if(&other == this) return *this; |
| foreign_void_weak_ptr(other).swap(*this); |
| return *this; |
| } |
| void swap(foreign_void_weak_ptr &other) |
| { |
| boost::swap(_p, other._p); |
| } |
| foreign_void_shared_ptr lock() const |
| { |
| return _p->lock(); |
| } |
| bool expired() const |
| { |
| return _p->expired(); |
| } |
| private: |
| boost::scoped_ptr<foreign_weak_ptr_impl_base> _p; |
| }; |
| } // namespace detail |
| |
| } // namespace signals2 |
| } // namespace boost |
| |
| #endif // BOOST_SIGNALS2_FOREIGN_PTR_HPP |