|
| 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 | + |
| 6 | +// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation. |
| 7 | + |
| 8 | +#ifndef BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_ |
| 9 | +#define BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_ |
| 10 | + |
| 11 | +#include <memory> |
| 12 | +#include <utility> |
| 13 | +#include <boost/iterator/iterator_adaptor.hpp> |
| 14 | + |
| 15 | +namespace boost { |
| 16 | + |
| 17 | +// For backward compatibility with boost::shared_ptr |
| 18 | +template< class T > |
| 19 | +class shared_ptr; |
| 20 | + |
| 21 | +namespace iterators { |
| 22 | +namespace detail { |
| 23 | + |
| 24 | +// Fake deleter that holds an instance of boost::shared_ptr and through it keeps the pointed object from deletion |
| 25 | +template< typename T > |
| 26 | +class shared_container_iterator_bsptr_holder |
| 27 | +{ |
| 28 | +private: |
| 29 | + boost::shared_ptr< T > m_ptr; |
| 30 | + |
| 31 | +public: |
| 32 | + explicit shared_container_iterator_bsptr_holder(boost::shared_ptr< T > const& ptr) : |
| 33 | + m_ptr(ptr) |
| 34 | + {} |
| 35 | + |
| 36 | + void operator()(T*) const noexcept {} |
| 37 | +}; |
| 38 | + |
| 39 | +} // namespace detail |
| 40 | + |
| 41 | +template< typename Container > |
| 42 | +class shared_container_iterator : |
| 43 | + public iterator_adaptor< |
| 44 | + shared_container_iterator< Container >, |
| 45 | + typename Container::iterator |
| 46 | + > |
| 47 | +{ |
| 48 | +private: |
| 49 | + using super_t = iterator_adaptor< |
| 50 | + shared_container_iterator< Container >, |
| 51 | + typename Container::iterator |
| 52 | + >; |
| 53 | + |
| 54 | + using iterator_t = typename Container::iterator; |
| 55 | + using container_ref_t = std::shared_ptr< Container >; |
| 56 | + |
| 57 | +public: |
| 58 | + shared_container_iterator() = default; |
| 59 | + |
| 60 | + shared_container_iterator(iterator_t const& x, container_ref_t const& c) : |
| 61 | + super_t(x), |
| 62 | + m_container_ref(c) |
| 63 | + {} |
| 64 | + |
| 65 | + // Constructor for backward compatibility with boost::shared_ptr |
| 66 | + shared_container_iterator(iterator_t const& x, boost::shared_ptr< Container > const& c) : |
| 67 | + super_t(x), |
| 68 | + m_container_ref(c.get(), detail::shared_container_iterator_bsptr_holder< Container >(c)) |
| 69 | + {} |
| 70 | + |
| 71 | +private: |
| 72 | + container_ref_t m_container_ref; |
| 73 | +}; |
| 74 | + |
| 75 | +template< typename Container > |
| 76 | +inline shared_container_iterator< Container > |
| 77 | +make_shared_container_iterator(typename Container::iterator iter, std::shared_ptr< Container > const& container) |
| 78 | +{ |
| 79 | + return shared_container_iterator< Container >(iter, container); |
| 80 | +} |
| 81 | + |
| 82 | +template< typename Container > |
| 83 | +inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > > |
| 84 | +make_shared_container_range(std::shared_ptr< Container > const& container) |
| 85 | +{ |
| 86 | + return std::make_pair |
| 87 | + ( |
| 88 | + iterators::make_shared_container_iterator(container->begin(), container), |
| 89 | + iterators::make_shared_container_iterator(container->end(), container) |
| 90 | + ); |
| 91 | +} |
| 92 | + |
| 93 | +// Factory functions for backward compatibility with boost::shared_ptr |
| 94 | +template< typename Container > |
| 95 | +inline shared_container_iterator< Container > |
| 96 | +make_shared_container_iterator(typename Container::iterator iter, boost::shared_ptr< Container > const& container) |
| 97 | +{ |
| 98 | + return shared_container_iterator< Container >(iter, container); |
| 99 | +} |
| 100 | + |
| 101 | +template< typename Container > |
| 102 | +inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > > |
| 103 | +make_shared_container_range(boost::shared_ptr< Container > const& container) |
| 104 | +{ |
| 105 | + std::shared_ptr< Container > c(container.get(), detail::shared_container_iterator_bsptr_holder< Container >(container)); |
| 106 | + return iterators::make_shared_container_range(std::move(c)); |
| 107 | +} |
| 108 | + |
| 109 | +} // namespace iterators |
| 110 | + |
| 111 | +using iterators::shared_container_iterator; |
| 112 | +using iterators::make_shared_container_iterator; |
| 113 | +using iterators::make_shared_container_range; |
| 114 | + |
| 115 | +} // namespace boost |
| 116 | + |
| 117 | +#endif // BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_ |
0 commit comments