slot_base.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Boost.Signals2 library
  2. // Copyright Frank Mori Hess 2007-2008.
  3. // Copyright Timmo Stange 2007.
  4. // Copyright Douglas Gregor 2001-2004. Use, modification and
  5. // distribution is subject to 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)
  8. // For more information, see http://www.boost.org
  9. #ifndef BOOST_SIGNALS2_SLOT_BASE_HPP
  10. #define BOOST_SIGNALS2_SLOT_BASE_HPP
  11. #include <boost/shared_ptr.hpp>
  12. #include <boost/weak_ptr.hpp>
  13. #include <boost/signals2/detail/foreign_ptr.hpp>
  14. #include <boost/signals2/expired_slot.hpp>
  15. #include <boost/signals2/signal_base.hpp>
  16. #include <boost/throw_exception.hpp>
  17. #include <boost/variant/apply_visitor.hpp>
  18. #include <boost/variant/variant.hpp>
  19. #include <vector>
  20. namespace boost
  21. {
  22. namespace signals2
  23. {
  24. namespace detail
  25. {
  26. class tracked_objects_visitor;
  27. class trackable_pointee;
  28. typedef boost::variant<boost::weak_ptr<trackable_pointee>, boost::weak_ptr<void>, detail::foreign_void_weak_ptr > void_weak_ptr_variant;
  29. typedef boost::variant<boost::shared_ptr<void>, detail::foreign_void_shared_ptr > void_shared_ptr_variant;
  30. class lock_weak_ptr_visitor
  31. {
  32. public:
  33. typedef void_shared_ptr_variant result_type;
  34. template<typename WeakPtr>
  35. result_type operator()(const WeakPtr &wp) const
  36. {
  37. return wp.lock();
  38. }
  39. // overload to prevent incrementing use count of shared_ptr associated
  40. // with signals2::trackable objects
  41. result_type operator()(const weak_ptr<trackable_pointee> &) const
  42. {
  43. return boost::shared_ptr<void>();
  44. }
  45. };
  46. class expired_weak_ptr_visitor
  47. {
  48. public:
  49. typedef bool result_type;
  50. template<typename WeakPtr>
  51. bool operator()(const WeakPtr &wp) const
  52. {
  53. return wp.expired();
  54. }
  55. };
  56. }
  57. class slot_base
  58. {
  59. public:
  60. typedef std::vector<detail::void_weak_ptr_variant> tracked_container_type;
  61. typedef std::vector<detail::void_shared_ptr_variant> locked_container_type;
  62. const tracked_container_type& tracked_objects() const {return _tracked_objects;}
  63. locked_container_type lock() const
  64. {
  65. locked_container_type locked_objects;
  66. tracked_container_type::const_iterator it;
  67. for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
  68. {
  69. locked_objects.push_back(apply_visitor(detail::lock_weak_ptr_visitor(), *it));
  70. if(apply_visitor(detail::expired_weak_ptr_visitor(), *it))
  71. {
  72. boost::throw_exception(expired_slot());
  73. }
  74. }
  75. return locked_objects;
  76. }
  77. bool expired() const
  78. {
  79. tracked_container_type::const_iterator it;
  80. for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
  81. {
  82. if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) return true;
  83. }
  84. return false;
  85. }
  86. protected:
  87. friend class detail::tracked_objects_visitor;
  88. void track_signal(const signal_base &signal)
  89. {
  90. _tracked_objects.push_back(signal.lock_pimpl());
  91. }
  92. tracked_container_type _tracked_objects;
  93. };
  94. }
  95. } // end namespace boost
  96. #endif // BOOST_SIGNALS2_SLOT_BASE_HPP