• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[section:shared_container Shared Container Iterator]
2
3Defined in header [@../../../boost/shared_container_iterator.hpp `boost/shared_container_iterator.hpp`].
4
5The purpose of the shared container iterator is to attach the lifetime
6of a container to the lifetime of its iterators. In other words, the
7container will not be deleted until after all its iterators are
8destroyed. The shared container iterator is typically used to
9implement functions that return iterators over a range of objects that
10only need to exist for the lifetime of the iterators. By returning a
11pair of shared iterators from a function, the callee can return a
12heap-allocated range of objects whose lifetime is automatically
13managed.
14
15The shared container iterator augments an iterator over a shared
16container. It maintains a reference count on the shared container. If
17only shared container iterators hold references to the container, the
18container's lifetime will end when the last shared container iterator
19over it is destroyed. In any case, the shared container is guaranteed
20to persist beyond the lifetime of all the iterators. In all other
21ways, the shared container iterator behaves the same as its base
22iterator.
23
24[h2 Synopsis]
25
26  namespace boost {
27    template <typename Container>
28    class shared_container_iterator;
29
30    template <typename Container>
31    shared_container_iterator<Container>
32    make_shared_container_iterator(typename Container::iterator base,
33      boost::shared_ptr<Container> const& container);
34
35    std::pair<
36      typename shared_container_iterator<Container>,
37      typename shared_container_iterator<Container>
38    >
39    make_shared_container_range(boost::shared_ptr<Container> const& container);
40  }
41
42[section:shared_container_type The Shared Container Iterator Type]
43
44  template <typename Container> class shared_container_iterator;
45
46The class template `shared_container_iterator` is the shared container
47iterator type. The `Container` template type argument must model the
48[@http://www.sgi.com/tech/stl/Container.html Container] concept.
49
50[h2 Example]
51
52The following example illustrates how to create an iterator that
53regulates the lifetime of a reference counted `std::vector`. Though the
54original shared pointer `ints` ceases to exist after `set_range()`
55returns, the `shared_counter_iterator` objects maintain references to
56the underlying vector and thereby extend the container's lifetime.
57
58[example_link shared_iterator_example1.cpp..`shared_iterator_example1.cpp`]:
59
60  #include "shared_container_iterator.hpp"
61  #include "boost/shared_ptr.hpp"
62  #include <algorithm>
63  #include <iostream>
64  #include <vector>
65
66  typedef boost::shared_container_iterator< std::vector<int> > iterator;
67
68
69  void set_range(iterator& i, iterator& end)  {
70
71    boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
72
73    ints->push_back(0);
74    ints->push_back(1);
75    ints->push_back(2);
76    ints->push_back(3);
77    ints->push_back(4);
78    ints->push_back(5);
79
80    i = iterator(ints->begin(),ints);
81    end = iterator(ints->end(),ints);
82  }
83
84
85  int main() {
86
87    iterator i,end;
88
89    set_range(i,end);
90
91    std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
92    std::cout.put('\n');
93
94    return 0;
95  }
96
97The output from this part is:
98
99[pre
1000,1,2,3,4,5,
101]
102
103[table Template Parameters
104  [[Parameter][Description]]
105  [[Container][The type of the container that we wish to iterate over. It must be a model of the Container concept.]]
106]
107
108[h2 Concepts]
109
110The `shared_container_iterator` type models the same iterator concept
111as the base iterator (`Container::iterator`).
112
113[h2 Operations]
114
115The `shared_container_iterator` type implements the member functions
116and operators required of the
117[@http://www.sgi.com/tech/stl/RandomAccessIterator.html Random Access
118Iterator] concept, though only operations defined for the base
119iterator will be valid. In addition it has the following constructor:
120
121  shared_container_iterator(Container::iterator const& it,
122                            boost::shared_ptr<Container> const& container)
123
124[endsect]
125
126[section:shared_container_object_generator The Shared Container Iterator Object Generator]
127
128  template <typename Container>
129  shared_container_iterator<Container>
130  make_shared_container_iterator(Container::iterator base,
131                                 boost::shared_ptr<Container> const& container)
132
133This function provides an alternative to directly constructing a
134`shared_container_iterator`. Using the object generator, a
135`shared_container_iterator` can be created and passed to a function without
136explicitly specifying its type.
137
138[h2 Example]
139
140This example, similar to the previous,
141uses `make_shared_container_iterator()` to create the iterators.
142
143[example_link shared_iterator_example2.cpp..`shared_iterator_example2.cpp`]:
144
145  #include "shared_container_iterator.hpp"
146  #include "boost/shared_ptr.hpp"
147  #include <algorithm>
148  #include <iterator>
149  #include <iostream>
150  #include <vector>
151
152
153  template <typename Iterator>
154  void print_range_nl (Iterator begin, Iterator end) {
155    typedef typename std::iterator_traits<Iterator>::value_type val;
156    std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
157    std::cout.put('\n');
158  }
159
160
161  int main() {
162
163    typedef boost::shared_ptr< std::vector<int> > ints_t;
164    {
165      ints_t ints(new std::vector<int>());
166
167      ints->push_back(0);
168      ints->push_back(1);
169      ints->push_back(2);
170      ints->push_back(3);
171      ints->push_back(4);
172      ints->push_back(5);
173
174      print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
175                     boost::make_shared_container_iterator(ints->end(),ints));
176    }
177
178
179
180    return 0;
181  }
182
183Observe that the `shared_container_iterator` type is never explicitly
184named. The output from this example is the same as the previous.
185
186[endsect]
187
188[section:shared_container_generator The Shared Container Iterator Range Generator]
189
190  template <typename Container>
191  std::pair<
192    shared_container_iterator<Container>,
193    shared_container_iterator<Container>
194  >
195  make_shared_container_range(boost::shared_ptr<Container> const& container);
196  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
197  std::make_pair(make_shared_container_iterator(container->begin(),container),
198                 make_shared_container_iterator(container->end(),container));
199
200[h2 Example]
201
202In the following example, a range of values is returned as a pair of shared_container_iterator objects.
203
204[example_link shared_iterator_example3.cpp..`shared_iterator_example3.cpp`]:
205
206  #include "shared_container_iterator.hpp"
207  #include "boost/shared_ptr.hpp"
208  #include "boost/tuple/tuple.hpp" // for boost::tie
209  #include <algorithm>              // for std::copy
210  #include <iostream>
211  #include <vector>
212
213
214  typedef boost::shared_container_iterator< std::vector<int> > iterator;
215
216  std::pair<iterator,iterator>
217  return_range() {
218    boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
219    range->push_back(0);
220    range->push_back(1);
221    range->push_back(2);
222    range->push_back(3);
223    range->push_back(4);
224    range->push_back(5);
225    return boost::make_shared_container_range(range);
226  }
227
228
229  int main() {
230
231
232    iterator i,end;
233
234    boost::tie(i,end) = return_range();
235
236    std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
237    std::cout.put('\n');
238
239    return 0;
240  }
241
242Though the range object only lives for the duration of the
243`return_range` call, the reference counted `std::vector` will live
244until `i` and `end` are both destroyed. The output from this example is
245the same as the previous two.
246
247[endsect]
248
249[endsect]
250