c++boost.gif (8819 bytes)

Shared Container Iterator

Defined in header 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 be deleted after the last iterator is destroyed. The shared container iterator is typically used to implement functions that return iterators over a range of objects that will only be needed for the lifetime of the iterators. By returning a pair of shared iterators from a function, the callee can ensure that the underlying container's lifetime will be properly managed.

The shared container iterator augments an iterator into a shared container with a reference counted pointer to the container. Assuming no other references exist to the container, it will be destroyed when the last shared container iterator is destroyed. In all other ways, the shared container iterator behaves the same as its base iterator.

Synopsis

namespace boost {
  template <typename Container>
  class shared_container_iterator_generator;

  template <typename Container>
  typename shared_container_iterator_generator<Container>::type
  make_shared_container_iterator(typename Container::iterator base, 
    boost::shared_ptr<Container> const& container);

  std::pair<
    typename shared_container_iterator_generator<Container>::type,
    typename shared_container_iterator_generator<Container>::type
  >
  make_shared_container_range(boost::shared_ptr<Container> const& container);

}

The Shared Container Iterator Type Generator

The class shared_container_iterator_generator is a helper class to construct a shared container iterator type. The template parameter for this class is a type that models the Container concept.
template <typename Container>
class shared_container_iterator_generator
{
public:
    typedef iterator_adaptor<...> type;
};

Example

The following example illustrates how to use the shared_counter_iterator_generator to create an iterator that regulates the lifetime of a reference counted std::vector. Though the original shared_ptr to the vector ceases to exist, the shared_counter_iterators extend the lifetime of the container.

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_generator< std::vector<int> >::type 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,

Template Parameters

ParameterDescription
Container The type of the container that we wish to iterate over. It must be a model of the Container concept.

Model of

The shared container iterator adaptor (the type shared_container_iterator_generator<...>::type) models the same iterator concept as the base iterator (Container::iterator) up to Random Access Iterator.

Members

The shared container iterator type implements the member functions and operators required of the 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_generator::type(Container::iterator const& it,
                                          boost::shared_ptr<Container> const& container)


The Shared Container Iterator Object Generator

template <typename Container>
typename shared_container_iterator_generator<AdaptableUnaryFunction,BaseIterator>::type
make_shared_container_iterator(Container::iterator base,
                               boost::shared_ptr<Container> const& container)
This function provides an alternative to using the shared container iterator type generator to create the iterator type before construction. Using the object generator, a shared container iterator can be created and passed to a function without explicitly specifying its type.

Example

This example, similar to the previous, uses make_shared_container_iterator() to create the iterators.

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.

The Shared Container Iterator Range Generator

template <typename Container>
std::pair<
  typename shared_container_iterator_generator<Container>::type,
  typename shared_container_iterator_generator<Container>::type
>
make_shared_container_range(boost::shared_ptr<Container> const& container);
Class shared_container_iterator is meant primarily to return via 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. This function is equivalent to
std::make_pair(make_shared_container_iterator(container->begin(),container),
               make_shared_container_iterator(container->end(),container));

Example

In the following example, a range of values is returned as a pair of shared_container_iterators.

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_generator< std::vector<int> >::type 
  function_iterator;

std::pair<function_iterator,function_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() {


  function_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.
Last modified: Wed Sep 4 15:52:17 EST 2002

© Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.