diff --git a/iterator_adaptors.htm b/iterator_adaptors.htm index c1c4e4a..c3d249e 100644 --- a/iterator_adaptors.htm +++ b/iterator_adaptors.htm @@ -128,6 +128,8 @@ Generator Iterator Adaptor
Dave
@@ -156,6 +158,9 @@
adaptor.
Toon Knapen contributed the permutation
iterator adaptor.
+ Ronald Garcia
+ contributed the shared container iterator
+ adaptor.
Class template
iterator_adaptor
diff --git a/shared_container_iterator.html b/shared_container_iterator.html
new file mode 100644
index 0000000..487b932
--- /dev/null
+++ b/shared_container_iterator.html
@@ -0,0 +1,332 @@
+
+
+
+
+
+
+
+
+
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. + + +
+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 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, ++ +
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(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. + +
+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 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. + + +
© 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/shared_iterator_example1.cpp b/shared_iterator_example1.cpp new file mode 100644 index 0000000..db7b511 --- /dev/null +++ b/shared_iterator_example1.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