shared_container_iterator.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
  2. // distribute this software is granted provided this copyright notice appears
  3. // in all copies. This software is provided "as is" without express or implied
  4. // warranty, and with no claim as to its suitability for any purpose.
  5. // See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
  6. #ifndef BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
  7. #define BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
  8. #include <memory>
  9. #include <utility>
  10. #include <boost/iterator/iterator_adaptor.hpp>
  11. namespace boost {
  12. // For backward compatibility with boost::shared_ptr
  13. template< class T >
  14. class shared_ptr;
  15. namespace iterators {
  16. namespace detail {
  17. // Fake deleter that holds an instance of boost::shared_ptr and through it keeps the pointed object from deletion
  18. template< typename T >
  19. class shared_container_iterator_bsptr_holder
  20. {
  21. private:
  22. boost::shared_ptr< T > m_ptr;
  23. public:
  24. explicit shared_container_iterator_bsptr_holder(boost::shared_ptr< T > const& ptr) :
  25. m_ptr(ptr)
  26. {}
  27. void operator()(T*) const noexcept {}
  28. };
  29. } // namespace detail
  30. template< typename Container >
  31. class shared_container_iterator :
  32. public iterator_adaptor<
  33. shared_container_iterator< Container >,
  34. typename Container::iterator
  35. >
  36. {
  37. private:
  38. using super_t = iterator_adaptor<
  39. shared_container_iterator< Container >,
  40. typename Container::iterator
  41. >;
  42. using iterator_t = typename Container::iterator;
  43. using container_ref_t = std::shared_ptr< Container >;
  44. public:
  45. shared_container_iterator() = default;
  46. shared_container_iterator(iterator_t const& x, container_ref_t const& c) :
  47. super_t(x),
  48. m_container_ref(c)
  49. {}
  50. // Constructor for backward compatibility with boost::shared_ptr
  51. shared_container_iterator(iterator_t const& x, boost::shared_ptr< Container > const& c) :
  52. super_t(x),
  53. m_container_ref(c.get(), detail::shared_container_iterator_bsptr_holder< Container >(c))
  54. {}
  55. private:
  56. container_ref_t m_container_ref;
  57. };
  58. template< typename Container >
  59. inline shared_container_iterator< Container >
  60. make_shared_container_iterator(typename Container::iterator iter, std::shared_ptr< Container > const& container)
  61. {
  62. return shared_container_iterator< Container >(iter, container);
  63. }
  64. template< typename Container >
  65. inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > >
  66. make_shared_container_range(std::shared_ptr< Container > const& container)
  67. {
  68. return std::make_pair
  69. (
  70. iterators::make_shared_container_iterator(container->begin(), container),
  71. iterators::make_shared_container_iterator(container->end(), container)
  72. );
  73. }
  74. // Factory functions for backward compatibility with boost::shared_ptr
  75. template< typename Container >
  76. inline shared_container_iterator< Container >
  77. make_shared_container_iterator(typename Container::iterator iter, boost::shared_ptr< Container > const& container)
  78. {
  79. return shared_container_iterator< Container >(iter, container);
  80. }
  81. template< typename Container >
  82. inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > >
  83. make_shared_container_range(boost::shared_ptr< Container > const& container)
  84. {
  85. std::shared_ptr< Container > c(container.get(), detail::shared_container_iterator_bsptr_holder< Container >(container));
  86. return iterators::make_shared_container_range(std::move(c));
  87. }
  88. } // namespace iterators
  89. using iterators::shared_container_iterator;
  90. using iterators::make_shared_container_iterator;
  91. using iterators::make_shared_container_range;
  92. } // namespace boost
  93. #endif // BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_