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 @@ + + +
+ + + +
+
++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. + + +
+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);
+
+
+}
+
+
+
+template <typename Container>
+class shared_container_iterator_generator
+{
+public:
+ typedef iterator_adaptor<...> type;
+};
+
+
++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, ++ +
| Parameter | Description | +
|---|---|
| Container | +The type of the container that we wish to iterate over. It must be +a model of the +Container +concept. + | +
+shared_container_iterator_generator::type(Container::iterator const& it, + boost::shared_ptr<Container> const& container) ++ +
+
+ + +
+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. + +
+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.
+
++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)); ++ +
+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.
+
+
+© 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