# 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_iterator`s 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

Parameter | Description
--- | ---
`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_iterator`s.

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.