123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- [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]
|