Squashed 'third_party/boostorg/iterator/' content from commit b2adecb

Change-Id: I284a73816f9cc846742923879275b84c6e0c915c
git-subtree-dir: third_party/boostorg/iterator
git-subtree-split: b2adecb951af025698618f19a3c838bd314966dc
diff --git a/doc/quickbook/shared_container_iterator.qbk b/doc/quickbook/shared_container_iterator.qbk
new file mode 100644
index 0000000..d48658c
--- /dev/null
+++ b/doc/quickbook/shared_container_iterator.qbk
@@ -0,0 +1,248 @@
+
+[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.
+
+[@../../example/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.
+
+[@../../example/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.
+
+[@../../example/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]
\ No newline at end of file