| 1 | <html> |
|---|
| 2 | |
|---|
| 3 | <head> |
|---|
| 4 | <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> |
|---|
| 5 | <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> |
|---|
| 6 | <meta name="ProgId" content="FrontPage.Editor.Document"> |
|---|
| 7 | <title>Shared Container Iterator Documentation</title> |
|---|
| 8 | </head> |
|---|
| 9 | |
|---|
| 10 | <body bgcolor="#FFFFFF" text="#000000"> |
|---|
| 11 | |
|---|
| 12 | <img src="../../boost.png" alt="boost.png (6897 bytes)" |
|---|
| 13 | align="center" width="277" height="86"> |
|---|
| 14 | |
|---|
| 15 | <h1>Shared Container Iterator</h1> |
|---|
| 16 | |
|---|
| 17 | Defined in header |
|---|
| 18 | <a href="../../boost/shared_container_iterator.hpp">boost/shared_container_iterator.hpp</a> |
|---|
| 19 | |
|---|
| 20 | <p> |
|---|
| 21 | The purpose of the shared container iterator is to attach the lifetime |
|---|
| 22 | of a container to the lifetime of its iterators. In other words, the |
|---|
| 23 | container will not be deleted until after all its iterators are |
|---|
| 24 | destroyed. The shared container iterator is typically used to |
|---|
| 25 | implement functions that return iterators over a range of objects that |
|---|
| 26 | only need to exist for the lifetime of the iterators. By returning a |
|---|
| 27 | pair of shared iterators from a function, the callee can return a |
|---|
| 28 | heap-allocated range of objects whose lifetime is automatically managed. |
|---|
| 29 | <p> |
|---|
| 30 | The shared container iterator augments an iterator over a shared |
|---|
| 31 | container. It maintains a reference count on the shared |
|---|
| 32 | container. If only shared container iterators hold references to |
|---|
| 33 | the container, the container's lifetime will end when the last shared |
|---|
| 34 | container iterator over it is destroyed. In any case, the shared |
|---|
| 35 | container is guaranteed to persist beyond the lifetime of all |
|---|
| 36 | the iterators. In all other ways, the |
|---|
| 37 | shared container iterator behaves the same as its base iterator. |
|---|
| 38 | |
|---|
| 39 | |
|---|
| 40 | <h2>Synopsis</h2> |
|---|
| 41 | |
|---|
| 42 | <pre> |
|---|
| 43 | namespace boost { |
|---|
| 44 | template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>> |
|---|
| 45 | class shared_container_iterator; |
|---|
| 46 | |
|---|
| 47 | template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>> |
|---|
| 48 | shared_container_iterator<Container> |
|---|
| 49 | make_shared_container_iterator(typename Container::iterator base, |
|---|
| 50 | boost::shared_ptr<Container> const& container); |
|---|
| 51 | |
|---|
| 52 | std::pair< |
|---|
| 53 | typename shared_container_iterator<Container>, |
|---|
| 54 | typename shared_container_iterator<Container> |
|---|
| 55 | > |
|---|
| 56 | make_shared_container_range(boost::shared_ptr<Container> const& container); |
|---|
| 57 | } |
|---|
| 58 | </pre> |
|---|
| 59 | |
|---|
| 60 | <hr> |
|---|
| 61 | |
|---|
| 62 | <h2><a name="generator">The Shared Container Iterator Type</a></h2> |
|---|
| 63 | |
|---|
| 64 | <pre> |
|---|
| 65 | template <typename Container> class shared_container_iterator; |
|---|
| 66 | </pre> |
|---|
| 67 | |
|---|
| 68 | The class template <tt>shared_container_iterator</tt> |
|---|
| 69 | is the shared container iterator type. The <tt>Container</tt> template |
|---|
| 70 | type argument must model the |
|---|
| 71 | <a href="http://www.sgi.com/tech/stl/Container.html">Container</a> |
|---|
| 72 | concept. |
|---|
| 73 | |
|---|
| 74 | <h3>Example</h3> |
|---|
| 75 | |
|---|
| 76 | <p> |
|---|
| 77 | The following example illustrates how to create an iterator that |
|---|
| 78 | regulates the lifetime of a reference counted <tt>std::vector</tt>. |
|---|
| 79 | Though the original shared pointer <tt>ints</tt> ceases to exist |
|---|
| 80 | after <tt>set_range()</tt> returns, the |
|---|
| 81 | <tt>shared_counter_iterator</tt> objects maintain references to the |
|---|
| 82 | underlying vector and thereby extend the container's lifetime. |
|---|
| 83 | <p> |
|---|
| 84 | <a href="./shared_iterator_example1.cpp">shared_iterator_example1.cpp</a>: |
|---|
| 85 | <PRE> |
|---|
| 86 | <font color="#008040">#include "shared_container_iterator.hpp"</font> |
|---|
| 87 | <font color="#008040">#include "boost/shared_ptr.hpp"</font> |
|---|
| 88 | <font color="#008040">#include <algorithm></font> |
|---|
| 89 | <font color="#008040">#include <iostream></font> |
|---|
| 90 | <font color="#008040">#include <vector></font> |
|---|
| 91 | |
|---|
| 92 | <B>typedef</B> boost::shared_container_iterator< std::vector<<B>int</B>> > iterator; |
|---|
| 93 | |
|---|
| 94 | |
|---|
| 95 | <B>void</B> set_range(iterator& i, iterator& end) { |
|---|
| 96 | |
|---|
| 97 | boost::shared_ptr< std::vector<<B>int</B>> > ints(<B>new</B> std::vector<<B>int</B>>()); |
|---|
| 98 | |
|---|
| 99 | ints->push_back(<font color="#0000A0">0</font>); |
|---|
| 100 | ints->push_back(<font color="#0000A0">1</font>); |
|---|
| 101 | ints->push_back(<font color="#0000A0">2</font>); |
|---|
| 102 | ints->push_back(<font color="#0000A0">3</font>); |
|---|
| 103 | ints->push_back(<font color="#0000A0">4</font>); |
|---|
| 104 | ints->push_back(<font color="#0000A0">5</font>); |
|---|
| 105 | |
|---|
| 106 | i = iterator(ints->begin(),ints); |
|---|
| 107 | end = iterator(ints->end(),ints); |
|---|
| 108 | } |
|---|
| 109 | |
|---|
| 110 | |
|---|
| 111 | <B>int</B> main() { |
|---|
| 112 | |
|---|
| 113 | iterator i,end; |
|---|
| 114 | |
|---|
| 115 | set_range(i,end); |
|---|
| 116 | |
|---|
| 117 | std::copy(i,end,std::ostream_iterator<<B>int</B>>(std::cout,<font color="#0000FF">","</font>)); |
|---|
| 118 | std::cout.put(<font color="#0000FF">'\n'</font>); |
|---|
| 119 | |
|---|
| 120 | <B>return</B> <font color="#0000A0">0</font>; |
|---|
| 121 | } |
|---|
| 122 | </PRE> |
|---|
| 123 | |
|---|
| 124 | The output from this part is: |
|---|
| 125 | <pre> |
|---|
| 126 | 0,1,2,3,4,5, |
|---|
| 127 | </pre> |
|---|
| 128 | |
|---|
| 129 | <h3>Template Parameters</h3> |
|---|
| 130 | |
|---|
| 131 | <Table border> |
|---|
| 132 | <TR> |
|---|
| 133 | <TH>Parameter</TH><TH>Description</TH> |
|---|
| 134 | </TR> |
|---|
| 135 | |
|---|
| 136 | <TR> |
|---|
| 137 | <TD><a |
|---|
| 138 | href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a></TD> |
|---|
| 139 | <TD>The type of the container that we wish to iterate over. It must be |
|---|
| 140 | a model of the |
|---|
| 141 | <a href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a> |
|---|
| 142 | concept. |
|---|
| 143 | </TD> |
|---|
| 144 | </TR> |
|---|
| 145 | </Table> |
|---|
| 146 | |
|---|
| 147 | <h3>Model of</h3> |
|---|
| 148 | |
|---|
| 149 | The <tt>shared_container_iterator<Container></tt> type models the |
|---|
| 150 | same iterator concept as the base iterator |
|---|
| 151 | (<tt>Container::iterator</tt>). |
|---|
| 152 | |
|---|
| 153 | <h3>Members</h3> |
|---|
| 154 | |
|---|
| 155 | The shared container iterator type implements the member functions and |
|---|
| 156 | operators required of the <a |
|---|
| 157 | href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a> |
|---|
| 158 | concept, though only operations defined for the base iterator will be valid. |
|---|
| 159 | In addition it has the following constructor: |
|---|
| 160 | |
|---|
| 161 | <pre> |
|---|
| 162 | shared_container_iterator(Container::iterator const& it, |
|---|
| 163 | boost::shared_ptr<Container> const& container) |
|---|
| 164 | </pre> |
|---|
| 165 | |
|---|
| 166 | <p> |
|---|
| 167 | <hr> |
|---|
| 168 | <p> |
|---|
| 169 | |
|---|
| 170 | |
|---|
| 171 | <h2><a name="make_iterator">The Shared Container Iterator Object Generator</a></h2> |
|---|
| 172 | |
|---|
| 173 | <pre> |
|---|
| 174 | template <typename Container> |
|---|
| 175 | shared_container_iterator<Container> |
|---|
| 176 | make_shared_container_iterator(Container::iterator base, |
|---|
| 177 | boost::shared_ptr<Container> const& container) |
|---|
| 178 | </pre> |
|---|
| 179 | |
|---|
| 180 | This function provides an alternative to directly constructing a |
|---|
| 181 | shared container iterator. Using the object generator, a shared |
|---|
| 182 | container iterator can be created and passed to a function without |
|---|
| 183 | explicitly specifying its type. |
|---|
| 184 | |
|---|
| 185 | <h3>Example</h3> |
|---|
| 186 | |
|---|
| 187 | This example, similar to the previous, uses |
|---|
| 188 | <tt>make_shared_container_iterator()</tt> to create the iterators. |
|---|
| 189 | |
|---|
| 190 | <p> |
|---|
| 191 | <a href="./shared_iterator_example2.cpp">shared_iterator_example2.cpp</a>: |
|---|
| 192 | |
|---|
| 193 | <PRE> |
|---|
| 194 | <font color="#008040">#include "shared_container_iterator.hpp"</font> |
|---|
| 195 | <font color="#008040">#include "boost/shared_ptr.hpp"</font> |
|---|
| 196 | <font color="#008040">#include <algorithm></font> |
|---|
| 197 | <font color="#008040">#include <iterator></font> |
|---|
| 198 | <font color="#008040">#include <iostream></font> |
|---|
| 199 | <font color="#008040">#include <vector></font> |
|---|
| 200 | |
|---|
| 201 | |
|---|
| 202 | <B>template</B> <<B>typename</B> Iterator> |
|---|
| 203 | <B>void</B> print_range_nl (Iterator begin, Iterator end) { |
|---|
| 204 | <B>typedef</B> <B>typename</B> std::iterator_traits<Iterator>::value_type val; |
|---|
| 205 | std::copy(begin,end,std::ostream_iterator<val>(std::cout,<font color="#0000FF">","</font>)); |
|---|
| 206 | std::cout.put(<font color="#0000FF">'\n'</font>); |
|---|
| 207 | } |
|---|
| 208 | |
|---|
| 209 | |
|---|
| 210 | <B>int</B> main() { |
|---|
| 211 | |
|---|
| 212 | <B>typedef</B> boost::shared_ptr< std::vector<<B>int</B>> > ints_t; |
|---|
| 213 | { |
|---|
| 214 | ints_t ints(<B>new</B> std::vector<<B>int</B>>()); |
|---|
| 215 | |
|---|
| 216 | ints->push_back(<font color="#0000A0">0</font>); |
|---|
| 217 | ints->push_back(<font color="#0000A0">1</font>); |
|---|
| 218 | ints->push_back(<font color="#0000A0">2</font>); |
|---|
| 219 | ints->push_back(<font color="#0000A0">3</font>); |
|---|
| 220 | ints->push_back(<font color="#0000A0">4</font>); |
|---|
| 221 | ints->push_back(<font color="#0000A0">5</font>); |
|---|
| 222 | |
|---|
| 223 | print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints), |
|---|
| 224 | boost::make_shared_container_iterator(ints->end(),ints)); |
|---|
| 225 | } |
|---|
| 226 | |
|---|
| 227 | |
|---|
| 228 | |
|---|
| 229 | <B>return</B> <font color="#0000A0">0</font>; |
|---|
| 230 | } |
|---|
| 231 | </PRE> |
|---|
| 232 | |
|---|
| 233 | Observe that the <tt>shared_container_iterator</tt> type is never |
|---|
| 234 | explicitly named. The output from this example is the same as the previous. |
|---|
| 235 | |
|---|
| 236 | <h2><a name="make_range">The Shared Container Iterator Range Generator</a></h2> |
|---|
| 237 | |
|---|
| 238 | <pre> |
|---|
| 239 | template <typename Container> |
|---|
| 240 | std::pair< |
|---|
| 241 | shared_container_iterator<Container>, |
|---|
| 242 | shared_container_iterator<Container> |
|---|
| 243 | > |
|---|
| 244 | make_shared_container_range(boost::shared_ptr<Container> const& container); |
|---|
| 245 | </pre> |
|---|
| 246 | |
|---|
| 247 | Class <tt>shared_container_iterator</tt> is meant primarily to return, |
|---|
| 248 | using iterators, a range of values that we can guarantee will be alive as |
|---|
| 249 | long as the iterators are. This is a convenience |
|---|
| 250 | function to do just that. It is equivalent to |
|---|
| 251 | |
|---|
| 252 | <pre> |
|---|
| 253 | std::make_pair(make_shared_container_iterator(container->begin(),container), |
|---|
| 254 | make_shared_container_iterator(container->end(),container)); |
|---|
| 255 | </pre> |
|---|
| 256 | |
|---|
| 257 | <h3>Example</h3> |
|---|
| 258 | |
|---|
| 259 | In the following example, a range of values is returned as a pair of |
|---|
| 260 | <tt>shared_container_iterator</tt> objects. |
|---|
| 261 | |
|---|
| 262 | |
|---|
| 263 | <p> |
|---|
| 264 | <a href="./shared_iterator_example3.cpp">shared_iterator_example3.cpp</a>: |
|---|
| 265 | |
|---|
| 266 | <PRE> |
|---|
| 267 | <font color="#008040">#include "shared_container_iterator.hpp"</font> |
|---|
| 268 | <font color="#008040">#include "boost/shared_ptr.hpp"</font> |
|---|
| 269 | <font color="#008040">#include "boost/tuple/tuple.hpp" // for boost::tie</font> |
|---|
| 270 | <font color="#008040">#include <algorithm> // for std::copy</font> |
|---|
| 271 | <font color="#008040">#include <iostream> </font> |
|---|
| 272 | <font color="#008040">#include <vector></font> |
|---|
| 273 | |
|---|
| 274 | |
|---|
| 275 | <B>typedef</B> boost::shared_container_iterator< std::vector<<B>int</B>> > iterator; |
|---|
| 276 | |
|---|
| 277 | std::pair<iterator,iterator> |
|---|
| 278 | return_range() { |
|---|
| 279 | boost::shared_ptr< std::vector<<B>int</B>> > range(<B>new</B> std::vector<<B>int</B>>()); |
|---|
| 280 | range->push_back(<font color="#0000A0">0</font>); |
|---|
| 281 | range->push_back(<font color="#0000A0">1</font>); |
|---|
| 282 | range->push_back(<font color="#0000A0">2</font>); |
|---|
| 283 | range->push_back(<font color="#0000A0">3</font>); |
|---|
| 284 | range->push_back(<font color="#0000A0">4</font>); |
|---|
| 285 | range->push_back(<font color="#0000A0">5</font>); |
|---|
| 286 | <B>return</B> boost::make_shared_container_range(range); |
|---|
| 287 | } |
|---|
| 288 | |
|---|
| 289 | |
|---|
| 290 | <B>int</B> main() { |
|---|
| 291 | |
|---|
| 292 | |
|---|
| 293 | iterator i,end; |
|---|
| 294 | |
|---|
| 295 | boost::tie(i,end) = return_range(); |
|---|
| 296 | |
|---|
| 297 | std::copy(i,end,std::ostream_iterator<<B>int</B>>(std::cout,<font color="#0000FF">","</font>)); |
|---|
| 298 | std::cout.put(<font color="#0000FF">'\n'</font>); |
|---|
| 299 | |
|---|
| 300 | <B>return</B> <font color="#0000A0">0</font>; |
|---|
| 301 | } |
|---|
| 302 | </PRE> |
|---|
| 303 | |
|---|
| 304 | Though the <tt>range</tt> object only lives for the duration of the |
|---|
| 305 | <tt>return_range</tt> call, the reference counted |
|---|
| 306 | <tt>std::vector</tt> will live until <tt>i</tt> and <tt>end</tt> |
|---|
| 307 | are both destroyed. The output from this example is the same as |
|---|
| 308 | the previous two. |
|---|
| 309 | |
|---|
| 310 | |
|---|
| 311 | <hr> |
|---|
| 312 | <!-- hhmts start --> |
|---|
| 313 | Last modified: Mon Aug 11 11:27:03 EST 2003 |
|---|
| 314 | <!-- hhmts end --> |
|---|
| 315 | <p>© Copyright 2003 The Trustees of Indiana University. |
|---|
| 316 | Use, modification and distribution is subject to the Boost Software |
|---|
| 317 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
|---|
| 318 | http:www.boost.org/LICENSE_1_0.txt)</p> |
|---|
| 319 | |
|---|
| 320 | </body> |
|---|
| 321 | |
|---|
| 322 | </html> |
|---|