foreign_ptr.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // helper code for dealing with tracking non-boost shared_ptr/weak_ptr
  2. // Copyright Frank Mori Hess 2009.
  3. // Distributed under the Boost Software License, Version
  4. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org/libs/signals2 for library home page.
  7. #ifndef BOOST_SIGNALS2_FOREIGN_PTR_HPP
  8. #define BOOST_SIGNALS2_FOREIGN_PTR_HPP
  9. #include <algorithm>
  10. #include <boost/config.hpp>
  11. #include <boost/assert.hpp>
  12. #include <boost/scoped_ptr.hpp>
  13. #include <boost/smart_ptr/bad_weak_ptr.hpp>
  14. #include <boost/utility/swap.hpp>
  15. #ifndef BOOST_NO_CXX11_SMART_PTR
  16. #include <memory>
  17. #endif
  18. namespace boost
  19. {
  20. template<typename T> class shared_ptr;
  21. template<typename T> class weak_ptr;
  22. namespace signals2
  23. {
  24. template<typename WeakPtr> struct weak_ptr_traits
  25. {};
  26. template<typename T> struct weak_ptr_traits<boost::weak_ptr<T> >
  27. {
  28. typedef boost::shared_ptr<T> shared_type;
  29. };
  30. #ifndef BOOST_NO_CXX11_SMART_PTR
  31. template<typename T> struct weak_ptr_traits<std::weak_ptr<T> >
  32. {
  33. typedef std::shared_ptr<T> shared_type;
  34. };
  35. #endif
  36. template<typename SharedPtr> struct shared_ptr_traits
  37. {};
  38. template<typename T> struct shared_ptr_traits<boost::shared_ptr<T> >
  39. {
  40. typedef boost::weak_ptr<T> weak_type;
  41. };
  42. #ifndef BOOST_NO_CXX11_SMART_PTR
  43. template<typename T> struct shared_ptr_traits<std::shared_ptr<T> >
  44. {
  45. typedef std::weak_ptr<T> weak_type;
  46. };
  47. #endif
  48. namespace detail
  49. {
  50. struct foreign_shared_ptr_impl_base
  51. {
  52. virtual ~foreign_shared_ptr_impl_base() {}
  53. virtual void* get() const = 0;
  54. virtual foreign_shared_ptr_impl_base * clone() const = 0;
  55. };
  56. template<typename FSP>
  57. class foreign_shared_ptr_impl: public foreign_shared_ptr_impl_base
  58. {
  59. public:
  60. foreign_shared_ptr_impl(const FSP &p): _p(p)
  61. {}
  62. virtual void * get() const
  63. {
  64. return _p.get();
  65. }
  66. virtual foreign_shared_ptr_impl * clone() const
  67. {
  68. return new foreign_shared_ptr_impl(*this);
  69. }
  70. private:
  71. FSP _p;
  72. };
  73. class foreign_void_shared_ptr
  74. {
  75. public:
  76. foreign_void_shared_ptr():
  77. _p(0)
  78. {}
  79. foreign_void_shared_ptr(const foreign_void_shared_ptr &other):
  80. _p(other._p->clone())
  81. {}
  82. template<typename FSP>
  83. explicit foreign_void_shared_ptr(const FSP &fsp):
  84. _p(new foreign_shared_ptr_impl<FSP>(fsp))
  85. {}
  86. ~foreign_void_shared_ptr()
  87. {
  88. delete _p;
  89. }
  90. foreign_void_shared_ptr & operator=(const foreign_void_shared_ptr &other)
  91. {
  92. if(&other == this) return *this;
  93. foreign_void_shared_ptr(other).swap(*this);
  94. return *this;
  95. }
  96. void swap(foreign_void_shared_ptr &other)
  97. {
  98. boost::swap(_p, other._p);
  99. }
  100. private:
  101. foreign_shared_ptr_impl_base *_p;
  102. };
  103. struct foreign_weak_ptr_impl_base
  104. {
  105. virtual ~foreign_weak_ptr_impl_base() {}
  106. virtual foreign_void_shared_ptr lock() const = 0;
  107. virtual bool expired() const = 0;
  108. virtual foreign_weak_ptr_impl_base * clone() const = 0;
  109. };
  110. template<typename FWP>
  111. class foreign_weak_ptr_impl: public foreign_weak_ptr_impl_base
  112. {
  113. public:
  114. foreign_weak_ptr_impl(const FWP &p): _p(p)
  115. {}
  116. virtual foreign_void_shared_ptr lock() const
  117. {
  118. return foreign_void_shared_ptr(_p.lock());
  119. }
  120. virtual bool expired() const
  121. {
  122. return _p.expired();
  123. }
  124. virtual foreign_weak_ptr_impl * clone() const
  125. {
  126. return new foreign_weak_ptr_impl(*this);
  127. }
  128. private:
  129. FWP _p;
  130. };
  131. class foreign_void_weak_ptr
  132. {
  133. public:
  134. foreign_void_weak_ptr()
  135. {}
  136. foreign_void_weak_ptr(const foreign_void_weak_ptr &other):
  137. _p(other._p->clone())
  138. {}
  139. template<typename FWP>
  140. explicit foreign_void_weak_ptr(const FWP &fwp):
  141. _p(new foreign_weak_ptr_impl<FWP>(fwp))
  142. {}
  143. foreign_void_weak_ptr & operator=(const foreign_void_weak_ptr &other)
  144. {
  145. if(&other == this) return *this;
  146. foreign_void_weak_ptr(other).swap(*this);
  147. return *this;
  148. }
  149. void swap(foreign_void_weak_ptr &other)
  150. {
  151. boost::swap(_p, other._p);
  152. }
  153. foreign_void_shared_ptr lock() const
  154. {
  155. return _p->lock();
  156. }
  157. bool expired() const
  158. {
  159. return _p->expired();
  160. }
  161. private:
  162. boost::scoped_ptr<foreign_weak_ptr_impl_base> _p;
  163. };
  164. } // namespace detail
  165. } // namespace signals2
  166. } // namespace boost
  167. #endif // BOOST_SIGNALS2_FOREIGN_PTR_HPP