mirror of
				https://github.com/boostorg/iterator.git
				synced 2025-11-04 10:21:38 +01:00 
			
		
		
		
	
		
			
	
	
		
			248 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			248 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:shared_container Shared Container Iterator]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Defined in header [@../../../boost/shared_container_iterator.hpp `boost/shared_container_iterator.hpp`].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The purpose of the shared container iterator is to attach the lifetime
							 | 
						||
| 
								 | 
							
								of a container to the lifetime of its iterators. In other words, the
							 | 
						||
| 
								 | 
							
								container will not be deleted until after all its iterators are
							 | 
						||
| 
								 | 
							
								destroyed. The shared container iterator is typically used to
							 | 
						||
| 
								 | 
							
								implement functions that return iterators over a range of objects that
							 | 
						||
| 
								 | 
							
								only need to exist for the lifetime of the iterators. By returning a
							 | 
						||
| 
								 | 
							
								pair of shared iterators from a function, the callee can return a
							 | 
						||
| 
								 | 
							
								heap-allocated range of objects whose lifetime is automatically
							 | 
						||
| 
								 | 
							
								managed.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The shared container iterator augments an iterator over a shared
							 | 
						||
| 
								 | 
							
								container. It maintains a reference count on the shared container. If
							 | 
						||
| 
								 | 
							
								only shared container iterators hold references to the container, the
							 | 
						||
| 
								 | 
							
								container's lifetime will end when the last shared container iterator
							 | 
						||
| 
								 | 
							
								over it is destroyed. In any case, the shared container is guaranteed
							 | 
						||
| 
								 | 
							
								to persist beyond the lifetime of all the iterators. In all other
							 | 
						||
| 
								 | 
							
								ways, the shared container iterator behaves the same as its base
							 | 
						||
| 
								 | 
							
								iterator.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h2 Synopsis]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  namespace boost {
							 | 
						||
| 
								 | 
							
								    template <typename Container>
							 | 
						||
| 
								 | 
							
								    class shared_container_iterator;
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    template <typename Container>
							 | 
						||
| 
								 | 
							
								    shared_container_iterator<Container>
							 | 
						||
| 
								 | 
							
								    make_shared_container_iterator(typename Container::iterator base, 
							 | 
						||
| 
								 | 
							
								      boost::shared_ptr<Container> const& container);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    std::pair<
							 | 
						||
| 
								 | 
							
								      typename shared_container_iterator<Container>,
							 | 
						||
| 
								 | 
							
								      typename shared_container_iterator<Container>
							 | 
						||
| 
								 | 
							
								    >
							 | 
						||
| 
								 | 
							
								    make_shared_container_range(boost::shared_ptr<Container> const& container);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:shared_container_type The Shared Container Iterator Type]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Container> class shared_container_iterator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The class template `shared_container_iterator` is the shared container
							 | 
						||
| 
								 | 
							
								iterator type. The `Container` template type argument must model the
							 | 
						||
| 
								 | 
							
								[@http://www.sgi.com/tech/stl/Container.html Container] concept. 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h2 Example]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The following example illustrates how to create an iterator that
							 | 
						||
| 
								 | 
							
								regulates the lifetime of a reference counted `std::vector`. Though the
							 | 
						||
| 
								 | 
							
								original shared pointer `ints` ceases to exist after `set_range()`
							 | 
						||
| 
								 | 
							
								returns, the `shared_counter_iterator` objects maintain references to
							 | 
						||
| 
								 | 
							
								the underlying vector and thereby extend the container's lifetime.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[@../../../libs/utility/shared_iterator_example1.cpp `shared_iterator_example1.cpp`]:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  #include "shared_container_iterator.hpp"
							 | 
						||
| 
								 | 
							
								  #include "boost/shared_ptr.hpp"
							 | 
						||
| 
								 | 
							
								  #include <algorithm>
							 | 
						||
| 
								 | 
							
								  #include <iostream>
							 | 
						||
| 
								 | 
							
								  #include <vector>
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								  typedef boost::shared_container_iterator< std::vector<int> > iterator;
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								  void set_range(iterator& i, iterator& end)  {
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    ints->push_back(0);
							 | 
						||
| 
								 | 
							
								    ints->push_back(1);
							 | 
						||
| 
								 | 
							
								    ints->push_back(2);
							 | 
						||
| 
								 | 
							
								    ints->push_back(3);
							 | 
						||
| 
								 | 
							
								    ints->push_back(4);
							 | 
						||
| 
								 | 
							
								    ints->push_back(5);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    i = iterator(ints->begin(),ints);
							 | 
						||
| 
								 | 
							
								    end = iterator(ints->end(),ints);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								  int main() {
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    iterator i,end;
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    set_range(i,end);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
							 | 
						||
| 
								 | 
							
								    std::cout.put('\n');
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The output from this part is:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  0,1,2,3,4,5,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[table Template Parameters
							 | 
						||
| 
								 | 
							
								  [[Parameter][Description]]
							 | 
						||
| 
								 | 
							
								  [[Container][The type of the container that we wish to iterate over. It must be a model of the Container concept.]]
							 | 
						||
| 
								 | 
							
								]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h2 Concepts]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The `shared_container_iterator` type models the same iterator concept
							 | 
						||
| 
								 | 
							
								as the base iterator (`Container::iterator`).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h2 Operations]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The `shared_container_iterator` type implements the member functions
							 | 
						||
| 
								 | 
							
								and operators required of the
							 | 
						||
| 
								 | 
							
								[@http://www.sgi.com/tech/stl/RandomAccessIterator.html Random Access
							 | 
						||
| 
								 | 
							
								Iterator] concept, though only operations defined for the base
							 | 
						||
| 
								 | 
							
								iterator will be valid. In addition it has the following constructor:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  shared_container_iterator(Container::iterator const& it,
							 | 
						||
| 
								 | 
							
								                            boost::shared_ptr<Container> const& container)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:shared_container_object_generator The Shared Container Iterator Object Generator]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Container>
							 | 
						||
| 
								 | 
							
								  shared_container_iterator<Container>
							 | 
						||
| 
								 | 
							
								  make_shared_container_iterator(Container::iterator base,
							 | 
						||
| 
								 | 
							
								                                 boost::shared_ptr<Container> const& container)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This function provides an alternative to directly constructing a
							 | 
						||
| 
								 | 
							
								`shared_container_iterator`. Using the object generator, a 
							 | 
						||
| 
								 | 
							
								`shared_container_iterator` can be created and passed to a function without
							 | 
						||
| 
								 | 
							
								explicitly specifying its type.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h2 Example]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This example, similar to the previous, 
							 | 
						||
| 
								 | 
							
								uses `make_shared_container_iterator()` to create the iterators.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[@../../../libs/utility/shared_iterator_example2.cpp `shared_iterator_example2.cpp`]:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  #include "shared_container_iterator.hpp"
							 | 
						||
| 
								 | 
							
								  #include "boost/shared_ptr.hpp"
							 | 
						||
| 
								 | 
							
								  #include <algorithm>
							 | 
						||
| 
								 | 
							
								  #include <iterator>
							 | 
						||
| 
								 | 
							
								  #include <iostream>
							 | 
						||
| 
								 | 
							
								  #include <vector>
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								  template <typename Iterator>
							 | 
						||
| 
								 | 
							
								  void print_range_nl (Iterator begin, Iterator end) {
							 | 
						||
| 
								 | 
							
								    typedef typename std::iterator_traits<Iterator>::value_type val;
							 | 
						||
| 
								 | 
							
								    std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
							 | 
						||
| 
								 | 
							
								    std::cout.put('\n');
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								  int main() {
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    typedef boost::shared_ptr< std::vector<int> > ints_t;
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      ints_t ints(new std::vector<int>());
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								      ints->push_back(0);
							 | 
						||
| 
								 | 
							
								      ints->push_back(1);
							 | 
						||
| 
								 | 
							
								      ints->push_back(2);
							 | 
						||
| 
								 | 
							
								      ints->push_back(3);
							 | 
						||
| 
								 | 
							
								      ints->push_back(4);
							 | 
						||
| 
								 | 
							
								      ints->push_back(5);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								      print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
							 | 
						||
| 
								 | 
							
								                     boost::make_shared_container_iterator(ints->end(),ints));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Observe that the `shared_container_iterator` type is never explicitly
							 | 
						||
| 
								 | 
							
								named. The output from this example is the same as the previous.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:shared_container_generator The Shared Container Iterator Range Generator]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename Container>
							 | 
						||
| 
								 | 
							
								  std::pair<
							 | 
						||
| 
								 | 
							
								    shared_container_iterator<Container>,
							 | 
						||
| 
								 | 
							
								    shared_container_iterator<Container>
							 | 
						||
| 
								 | 
							
								  >
							 | 
						||
| 
								 | 
							
								  make_shared_container_range(boost::shared_ptr<Container> const& container);
							 | 
						||
| 
								 | 
							
								  Class shared_container_iterator is meant primarily to return, using iterators, a range of values that we can guarantee will be alive as long as the iterators are. This is a convenience function to do just that. It is equivalent to
							 | 
						||
| 
								 | 
							
								  std::make_pair(make_shared_container_iterator(container->begin(),container),
							 | 
						||
| 
								 | 
							
								                 make_shared_container_iterator(container->end(),container));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h2 Example]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In the following example, a range of values is returned as a pair of shared_container_iterator objects.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[@../../../libs/utility/shared_iterator_example3.cpp `shared_iterator_example3.cpp`]:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  #include "shared_container_iterator.hpp"
							 | 
						||
| 
								 | 
							
								  #include "boost/shared_ptr.hpp"
							 | 
						||
| 
								 | 
							
								  #include "boost/tuple/tuple.hpp" // for boost::tie
							 | 
						||
| 
								 | 
							
								  #include <algorithm>              // for std::copy
							 | 
						||
| 
								 | 
							
								  #include <iostream>              
							 | 
						||
| 
								 | 
							
								  #include <vector>
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								  typedef boost::shared_container_iterator< std::vector<int> > iterator; 
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								  std::pair<iterator,iterator>
							 | 
						||
| 
								 | 
							
								  return_range() {
							 | 
						||
| 
								 | 
							
								    boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
							 | 
						||
| 
								 | 
							
								    range->push_back(0);
							 | 
						||
| 
								 | 
							
								    range->push_back(1);
							 | 
						||
| 
								 | 
							
								    range->push_back(2);
							 | 
						||
| 
								 | 
							
								    range->push_back(3);
							 | 
						||
| 
								 | 
							
								    range->push_back(4);
							 | 
						||
| 
								 | 
							
								    range->push_back(5);
							 | 
						||
| 
								 | 
							
								    return boost::make_shared_container_range(range);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								  int main() {
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    iterator i,end;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    boost::tie(i,end) = return_range();
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
							 | 
						||
| 
								 | 
							
								    std::cout.put('\n');
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Though the range object only lives for the duration of the
							 | 
						||
| 
								 | 
							
								`return_range` call, the reference counted `std::vector` will live
							 | 
						||
| 
								 | 
							
								until `i` and `end` are both destroyed. The output from this example is
							 | 
						||
| 
								 | 
							
								the same as the previous two.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 |