From 4b96e0e5f9e0c06070f5830711c2acad54a67994 Mon Sep 17 00:00:00 2001 From: Ronald Garcia Date: Mon, 2 Sep 2002 16:52:09 +0000 Subject: [PATCH] Initial Revision. [SVN r501] --- doc/shared_container_iterator.html | 333 ++++++++++++++++++++ example/shared_iterator_example1.cpp | 41 +++ example/shared_iterator_example2.cpp | 42 +++ example/shared_iterator_example3.cpp | 41 +++ include/boost/shared_container_iterator.hpp | 55 ++++ 5 files changed, 512 insertions(+) create mode 100644 doc/shared_container_iterator.html create mode 100644 example/shared_iterator_example1.cpp create mode 100644 example/shared_iterator_example2.cpp create mode 100644 example/shared_iterator_example3.cpp create mode 100644 include/boost/shared_container_iterator.hpp diff --git a/doc/shared_container_iterator.html b/doc/shared_container_iterator.html new file mode 100644 index 0000000..56ae221 --- /dev/null +++ b/doc/shared_container_iterator.html @@ -0,0 +1,333 @@ + + + + + + +Shared Container Iterator Documentation + + + + +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 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
ContainerThe 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(make_shared_container_iterator(ints->begin(),ints),
+		   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 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 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: Mon Sep 2 11:34:29 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.

+ + + + diff --git a/example/shared_iterator_example1.cpp b/example/shared_iterator_example1.cpp new file mode 100644 index 0000000..1aee968 --- /dev/null +++ b/example/shared_iterator_example1.cpp @@ -0,0 +1,41 @@ +// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +#include "boost/shared_container_iterator.hpp" +#include "boost/shared_ptr.hpp" +#include +#include +#include + +typedef shared_container_iterator_generator< std::vector >::type iterator; + + +void set_range(iterator& i, iterator& end) { + + boost::shared_ptr< std::vector > ints(new std::vector()); + + 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(std::cout,",")); + std::cout.put('\n'); + + return 0; +} diff --git a/example/shared_iterator_example2.cpp b/example/shared_iterator_example2.cpp new file mode 100644 index 0000000..438a21f --- /dev/null +++ b/example/shared_iterator_example2.cpp @@ -0,0 +1,42 @@ +// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +#include "boost/shared_container_iterator.hpp" +#include "boost/shared_ptr.hpp" +#include +#include +#include +#include + + +template +void print_range_nl (Iterator begin, Iterator end) { + typedef typename std::iterator_traits::value_type val; + std::copy(begin,end,std::ostream_iterator(std::cout,",")); + std::cout.put('\n'); +} + + +int main() { + + typedef boost::shared_ptr< std::vector > ints_t; + { + ints_t ints(new std::vector()); + + 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(make_shared_container_iterator(ints->begin(),ints), + make_shared_container_iterator(ints->end(),ints)); + } + + + + return 0; +} diff --git a/example/shared_iterator_example3.cpp b/example/shared_iterator_example3.cpp new file mode 100644 index 0000000..f798811 --- /dev/null +++ b/example/shared_iterator_example3.cpp @@ -0,0 +1,41 @@ +// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +#include "boost/shared_container_iterator.hpp" +#include "boost/shared_ptr.hpp" +#include "boost/tuple/tuple.hpp" // for boost::tie +#include // for std::copy +#include +#include + + +typedef shared_container_iterator_generator< std::vector >::type + function_iterator; + +std::pair +return_range() { + boost::shared_ptr< std::vector > range(new std::vector()); + 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 make_shared_container_range(range); +} + + +int main() { + + + function_iterator i,end; + + boost::tie(i,end) = return_range(); + + std::copy(i,end,std::ostream_iterator(std::cout,",")); + std::cout.put('\n'); + + return 0; +} diff --git a/include/boost/shared_container_iterator.hpp b/include/boost/shared_container_iterator.hpp new file mode 100644 index 0000000..dc8c777 --- /dev/null +++ b/include/boost/shared_container_iterator.hpp @@ -0,0 +1,55 @@ +// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + + +#ifndef SHARED_CONTAINER_ITERATOR_RG08102002_HPP +#define SHARED_CONTAINER_ITERATOR_RG08102002_HPP + +#include "boost/iterator_adaptors.hpp" +#include "boost/shared_ptr.hpp" +#include + + +template +struct shared_container_iterator_policies : + public boost::default_iterator_policies { + typedef boost::shared_ptr container_ref_t; + container_ref_t container_ref; + shared_container_iterator_policies(container_ref_t const& c) : + container_ref(c) { } + shared_container_iterator_policies() { } +}; + + +template +class shared_container_iterator_generator { + typedef typename Container::iterator iterator; + typedef shared_container_iterator_policies policy; +public: + typedef boost::iterator_adaptor type; +}; + +template +typename shared_container_iterator_generator::type +make_shared_container_iterator(typename Container::iterator iter, + boost::shared_ptr const& container) { + typedef typename shared_container_iterator_generator::type + iterator; + typedef shared_container_iterator_policies policy; + return iterator(iter,policy(container)); +} + +template +std::pair< + typename shared_container_iterator_generator::type, + typename shared_container_iterator_generator::type> +make_shared_container_range(boost::shared_ptr const& container) { + return + std::make_pair( + make_shared_container_iterator(container->begin(),container), + make_shared_container_iterator(container->end(),container)); +} + +#endif // SHARED_CONTAINER_ITERATOR_RG08102002_HPP