examples.html 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6. <meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
  7. <title>Boost Pointer Container Library</title>
  8. <style type="text/css">
  9. /*
  10. :Author: David Goodger (goodger@python.org)
  11. :Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
  12. :Copyright: This stylesheet has been placed in the public domain.
  13. Default cascading style sheet for the HTML output of Docutils.
  14. See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
  15. customize this style sheet.
  16. */
  17. /* used to remove borders from tables and images */
  18. .borderless, table.borderless td, table.borderless th {
  19. border: 0 }
  20. table.borderless td, table.borderless th {
  21. /* Override padding for "table.docutils td" with "! important".
  22. The right padding separates the table cells. */
  23. padding: 0 0.5em 0 0 ! important }
  24. .first {
  25. /* Override more specific margin styles with "! important". */
  26. margin-top: 0 ! important }
  27. .last, .with-subtitle {
  28. margin-bottom: 0 ! important }
  29. .hidden {
  30. display: none }
  31. .subscript {
  32. vertical-align: sub;
  33. font-size: smaller }
  34. .superscript {
  35. vertical-align: super;
  36. font-size: smaller }
  37. a.toc-backref {
  38. text-decoration: none ;
  39. color: black }
  40. blockquote.epigraph {
  41. margin: 2em 5em ; }
  42. dl.docutils dd {
  43. margin-bottom: 0.5em }
  44. object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  45. overflow: hidden;
  46. }
  47. /* Uncomment (and remove this text!) to get bold-faced definition list terms
  48. dl.docutils dt {
  49. font-weight: bold }
  50. */
  51. div.abstract {
  52. margin: 2em 5em }
  53. div.abstract p.topic-title {
  54. font-weight: bold ;
  55. text-align: center }
  56. div.admonition, div.attention, div.caution, div.danger, div.error,
  57. div.hint, div.important, div.note, div.tip, div.warning {
  58. margin: 2em ;
  59. border: medium outset ;
  60. padding: 1em }
  61. div.admonition p.admonition-title, div.hint p.admonition-title,
  62. div.important p.admonition-title, div.note p.admonition-title,
  63. div.tip p.admonition-title {
  64. font-weight: bold ;
  65. font-family: sans-serif }
  66. div.attention p.admonition-title, div.caution p.admonition-title,
  67. div.danger p.admonition-title, div.error p.admonition-title,
  68. div.warning p.admonition-title, .code .error {
  69. color: red ;
  70. font-weight: bold ;
  71. font-family: sans-serif }
  72. /* Uncomment (and remove this text!) to get reduced vertical space in
  73. compound paragraphs.
  74. div.compound .compound-first, div.compound .compound-middle {
  75. margin-bottom: 0.5em }
  76. div.compound .compound-last, div.compound .compound-middle {
  77. margin-top: 0.5em }
  78. */
  79. div.dedication {
  80. margin: 2em 5em ;
  81. text-align: center ;
  82. font-style: italic }
  83. div.dedication p.topic-title {
  84. font-weight: bold ;
  85. font-style: normal }
  86. div.figure {
  87. margin-left: 2em ;
  88. margin-right: 2em }
  89. div.footer, div.header {
  90. clear: both;
  91. font-size: smaller }
  92. div.line-block {
  93. display: block ;
  94. margin-top: 1em ;
  95. margin-bottom: 1em }
  96. div.line-block div.line-block {
  97. margin-top: 0 ;
  98. margin-bottom: 0 ;
  99. margin-left: 1.5em }
  100. div.sidebar {
  101. margin: 0 0 0.5em 1em ;
  102. border: medium outset ;
  103. padding: 1em ;
  104. background-color: #ffffee ;
  105. width: 40% ;
  106. float: right ;
  107. clear: right }
  108. div.sidebar p.rubric {
  109. font-family: sans-serif ;
  110. font-size: medium }
  111. div.system-messages {
  112. margin: 5em }
  113. div.system-messages h1 {
  114. color: red }
  115. div.system-message {
  116. border: medium outset ;
  117. padding: 1em }
  118. div.system-message p.system-message-title {
  119. color: red ;
  120. font-weight: bold }
  121. div.topic {
  122. margin: 2em }
  123. h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
  124. h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  125. margin-top: 0.4em }
  126. h1.title {
  127. text-align: center }
  128. h2.subtitle {
  129. text-align: center }
  130. hr.docutils {
  131. width: 75% }
  132. img.align-left, .figure.align-left, object.align-left, table.align-left {
  133. clear: left ;
  134. float: left ;
  135. margin-right: 1em }
  136. img.align-right, .figure.align-right, object.align-right, table.align-right {
  137. clear: right ;
  138. float: right ;
  139. margin-left: 1em }
  140. img.align-center, .figure.align-center, object.align-center {
  141. display: block;
  142. margin-left: auto;
  143. margin-right: auto;
  144. }
  145. table.align-center {
  146. margin-left: auto;
  147. margin-right: auto;
  148. }
  149. .align-left {
  150. text-align: left }
  151. .align-center {
  152. clear: both ;
  153. text-align: center }
  154. .align-right {
  155. text-align: right }
  156. /* reset inner alignment in figures */
  157. div.align-right {
  158. text-align: inherit }
  159. /* div.align-center * { */
  160. /* text-align: left } */
  161. .align-top {
  162. vertical-align: top }
  163. .align-middle {
  164. vertical-align: middle }
  165. .align-bottom {
  166. vertical-align: bottom }
  167. ol.simple, ul.simple {
  168. margin-bottom: 1em }
  169. ol.arabic {
  170. list-style: decimal }
  171. ol.loweralpha {
  172. list-style: lower-alpha }
  173. ol.upperalpha {
  174. list-style: upper-alpha }
  175. ol.lowerroman {
  176. list-style: lower-roman }
  177. ol.upperroman {
  178. list-style: upper-roman }
  179. p.attribution {
  180. text-align: right ;
  181. margin-left: 50% }
  182. p.caption {
  183. font-style: italic }
  184. p.credits {
  185. font-style: italic ;
  186. font-size: smaller }
  187. p.label {
  188. white-space: nowrap }
  189. p.rubric {
  190. font-weight: bold ;
  191. font-size: larger ;
  192. color: maroon ;
  193. text-align: center }
  194. p.sidebar-title {
  195. font-family: sans-serif ;
  196. font-weight: bold ;
  197. font-size: larger }
  198. p.sidebar-subtitle {
  199. font-family: sans-serif ;
  200. font-weight: bold }
  201. p.topic-title {
  202. font-weight: bold }
  203. pre.address {
  204. margin-bottom: 0 ;
  205. margin-top: 0 ;
  206. font: inherit }
  207. pre.literal-block, pre.doctest-block, pre.math, pre.code {
  208. margin-left: 2em ;
  209. margin-right: 2em }
  210. pre.code .ln { color: grey; } /* line numbers */
  211. pre.code, code { background-color: #eeeeee }
  212. pre.code .comment, code .comment { color: #5C6576 }
  213. pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
  214. pre.code .literal.string, code .literal.string { color: #0C5404 }
  215. pre.code .name.builtin, code .name.builtin { color: #352B84 }
  216. pre.code .deleted, code .deleted { background-color: #DEB0A1}
  217. pre.code .inserted, code .inserted { background-color: #A3D289}
  218. span.classifier {
  219. font-family: sans-serif ;
  220. font-style: oblique }
  221. span.classifier-delimiter {
  222. font-family: sans-serif ;
  223. font-weight: bold }
  224. span.interpreted {
  225. font-family: sans-serif }
  226. span.option {
  227. white-space: nowrap }
  228. span.pre {
  229. white-space: pre }
  230. span.problematic {
  231. color: red }
  232. span.section-subtitle {
  233. /* font-size relative to parent (h1..h6 element) */
  234. font-size: 80% }
  235. table.citation {
  236. border-left: solid 1px gray;
  237. margin-left: 1px }
  238. table.docinfo {
  239. margin: 2em 4em }
  240. table.docutils {
  241. margin-top: 0.5em ;
  242. margin-bottom: 0.5em }
  243. table.footnote {
  244. border-left: solid 1px black;
  245. margin-left: 1px }
  246. table.docutils td, table.docutils th,
  247. table.docinfo td, table.docinfo th {
  248. padding-left: 0.5em ;
  249. padding-right: 0.5em ;
  250. vertical-align: top }
  251. table.docutils th.field-name, table.docinfo th.docinfo-name {
  252. font-weight: bold ;
  253. text-align: left ;
  254. white-space: nowrap ;
  255. padding-left: 0 }
  256. /* "booktabs" style (no vertical lines) */
  257. table.docutils.booktabs {
  258. border: 0px;
  259. border-top: 2px solid;
  260. border-bottom: 2px solid;
  261. border-collapse: collapse;
  262. }
  263. table.docutils.booktabs * {
  264. border: 0px;
  265. }
  266. table.docutils.booktabs th {
  267. border-bottom: thin solid;
  268. text-align: left;
  269. }
  270. h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
  271. h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  272. font-size: 100% }
  273. ul.auto-toc {
  274. list-style-type: none }
  275. </style>
  276. </head>
  277. <body>
  278. <div class="document" id="boost-pointer-container-library">
  279. <h1 class="title"><img alt="Boost" src="boost.png" /> Pointer Container Library</h1>
  280. <h2 class="subtitle" id="examples">Examples</h2>
  281. <p>Some examples are given here and in the accompanying test files:</p>
  282. <div class="contents local topic" id="contents">
  283. <ul class="simple">
  284. <li><a class="reference internal" href="#null-pointers-cannot-be-stored-in-the-containers" id="id2">1. Null pointers cannot be stored in the containers</a></li>
  285. <li><a class="reference internal" href="#iterators-and-other-operations-return-indirected-values" id="id3">2. Iterators and other operations return indirected values</a></li>
  286. <li><a class="reference internal" href="#copy-semantics-of-pointer-containers" id="id4">3. Copy-semantics of pointer containers</a></li>
  287. <li><a class="reference internal" href="#making-a-non-copyable-type-cloneable" id="id5">4. Making a non-copyable type Cloneable</a></li>
  288. <li><a class="reference internal" href="#objects-are-cloned-before-insertion-inserted-pointers-are-owned-by-the-container" id="id6">5. Objects are cloned before insertion, inserted pointers are owned by the container</a></li>
  289. <li><a class="reference internal" href="#transferring-ownership-of-a-single-element" id="id7">6. Transferring ownership of a single element</a></li>
  290. <li><a class="reference internal" href="#transferring-ownership-of-pointers-between-different-pointer-containers" id="id8">7. Transferring ownership of pointers between different pointer containers</a></li>
  291. <li><a class="reference internal" href="#selected-test-files" id="id9">8. Selected test files</a></li>
  292. <li><a class="reference internal" href="#a-large-example" id="id10">9. A large example</a></li>
  293. </ul>
  294. </div>
  295. <div class="section" id="null-pointers-cannot-be-stored-in-the-containers">
  296. <span id="example-1"></span><h1><a class="toc-backref" href="#id2">1. Null pointers cannot be stored in the containers</a></h1>
  297. <pre class="literal-block">
  298. my_container.push_back( 0 ); // throws bad_ptr
  299. my_container.replace( an_iterator, 0 ); // throws bad_ptr
  300. my_container.insert( an_iterator, 0 ); // throws bad_ptr
  301. std::auto_ptr&lt;T&gt; p( 0 );
  302. my_container.push_back( p ); // throws bad_ptr
  303. </pre>
  304. </div>
  305. <div class="section" id="iterators-and-other-operations-return-indirected-values">
  306. <span id="example-2"></span><h1><a class="toc-backref" href="#id3">2. Iterators and other operations return indirected values</a></h1>
  307. <pre class="literal-block">
  308. ptr_vector&lt;X&gt; pvec;
  309. std::vector&lt;X*&gt; vec;
  310. *vec.begin() = new X; // fine, memory leak
  311. *pvec.begin() = new X; // compile time error
  312. ( *vec.begin() )-&gt;foo(); // call X::foo(), a bit clumsy
  313. pvec.begin()-&gt;foo(); // no indirection needed
  314. *vec.front() = X(); // overwrite first element
  315. pvec.front() = X(); // no indirection needed
  316. </pre>
  317. </div>
  318. <div class="section" id="copy-semantics-of-pointer-containers">
  319. <span id="example-3"></span><h1><a class="toc-backref" href="#id4">3. Copy-semantics of pointer containers</a></h1>
  320. <pre class="literal-block">
  321. ptr_vector&lt;T&gt; vec1;
  322. ...
  323. ptr_vector&lt;T&gt; vec2( vec1.clone() ); // deep copy objects of 'vec1' and use them to construct 'vec2', could be very expensive
  324. vec2 = vec1.release(); // give up ownership of pointers in 'vec1' and pass the ownership to 'vec2', rather cheap
  325. vec2.release(); // give up ownership; the objects will be deallocated if not assigned to another container
  326. vec1 = vec2; // deep copy objects of 'vec2' and assign them to 'vec1', could be very expensive
  327. ptr_vector&lt;T&gt; vec3( vec1 ); // deep copy objects of 'vec1', could be very expensive
  328. </pre>
  329. </div>
  330. <div class="section" id="making-a-non-copyable-type-cloneable">
  331. <span id="example-4"></span><h1><a class="toc-backref" href="#id5">4. Making a non-copyable type Cloneable</a></h1>
  332. <pre class="literal-block">
  333. // a class that has no normal copy semantics
  334. class X : boost::noncopyable { public: X* clone() const; ... };
  335. // this will be found by the library by argument dependent lookup (ADL)
  336. X* new_clone( const X&amp; x )
  337. { return x.clone(); }
  338. // we can now use the interface that requires cloneability
  339. ptr_vector&lt;X&gt; vec1, vec2;
  340. ...
  341. vec2 = vec1.clone(); // 'clone()' requires cloning &lt;g&gt;
  342. vec2.insert( vec2.end(), vec1.begin(), vec1.end() ); // inserting always means inserting clones
  343. </pre>
  344. </div>
  345. <div class="section" id="objects-are-cloned-before-insertion-inserted-pointers-are-owned-by-the-container">
  346. <span id="example-5"></span><h1><a class="toc-backref" href="#id6">5. Objects are cloned before insertion, inserted pointers are owned by the container</a></h1>
  347. <pre class="literal-block">
  348. class X { ... }; // assume 'X' is Cloneable
  349. X x; // and 'X' can be stack-allocated
  350. ptr_list&lt;X&gt; list;
  351. list.push_back( new_clone( x ) ); // insert a clone
  352. list.push_back( new X ); // always give the pointer directly to the container to avoid leaks
  353. list.push_back( &amp;x ); // don't do this!!!
  354. std::auto_ptr&lt;X&gt; p( new X );
  355. list.push_back( p ); // give up ownership
  356. BOOST_ASSERT( p.get() == 0 );
  357. </pre>
  358. </div>
  359. <div class="section" id="transferring-ownership-of-a-single-element">
  360. <span id="example-6"></span><h1><a class="toc-backref" href="#id7">6. Transferring ownership of a single element</a></h1>
  361. <pre class="literal-block">
  362. ptr_deque&lt;T&gt; deq;
  363. typedef ptr_deque&lt;T&gt;::auto_type auto_type;
  364. // ... fill the container somehow
  365. auto_type ptr = deq.pop_back(); // remove back element from container and give up ownership
  366. auto_type ptr2 = deq.release( deq.begin() + 2 ); // use an iterator to determine the element to release
  367. ptr = deq.pop_front(); // supported for 'ptr_list' and 'ptr_deque'
  368. deq.push_back( ptr.release() ); // give ownership back to the container
  369. </pre>
  370. </div>
  371. <div class="section" id="transferring-ownership-of-pointers-between-different-pointer-containers">
  372. <span id="example-7"></span><h1><a class="toc-backref" href="#id8">7. Transferring ownership of pointers between different pointer containers</a></h1>
  373. <pre class="literal-block">
  374. ptr_list&lt;X&gt; list; ptr_vector&lt;X&gt; vec;
  375. ...
  376. //
  377. // note: no cloning happens in these examples
  378. //
  379. list.transfer( list.begin(), vec.begin(), vec ); // make the first element of 'vec' the first element of 'list'
  380. vec.transfer( vec.end(), list.begin(), list.end(), list ); // put all the lists element into the vector
  381. </pre>
  382. <p>We can also transfer objects from <tt class="docutils literal">ptr_container&lt;Derived&gt;</tt> to <tt class="docutils literal">ptr_container&lt;Base&gt;</tt> without any problems.</p>
  383. </div>
  384. <div class="section" id="selected-test-files">
  385. <span id="example-8"></span><h1><a class="toc-backref" href="#id9">8. Selected test files</a></h1>
  386. <table class="docutils field-list" frame="void" rules="none">
  387. <col class="field-name" />
  388. <col class="field-body" />
  389. <tbody valign="top">
  390. <tr class="field"><th class="field-name" colspan="2"><a class="reference external" href="../test/incomplete_type_test.cpp">incomplete_type_test.cpp</a>:</th></tr>
  391. <tr class="field"><td>&nbsp;</td><td class="field-body">Shows how to implement the Composite pattern.</td>
  392. </tr>
  393. <tr class="field"><th class="field-name" colspan="2"><a class="reference external" href="../test/simple_test.cpp">simple_test.cpp</a>:</th></tr>
  394. <tr class="field"><td>&nbsp;</td><td class="field-body">Shows how the usage of pointer container compares with a
  395. container of smart pointers</td>
  396. </tr>
  397. <tr class="field"><th class="field-name" colspan="2"><a class="reference external" href="../test/view_example.cpp">view_example.cpp</a>:</th></tr>
  398. <tr class="field"><td>&nbsp;</td><td class="field-body">Shows how to use a pointer container as a view into other container</td>
  399. </tr>
  400. <tr class="field"><th class="field-name"><a class="reference external" href="../test/tree_test.cpp">tree_test.cpp</a>:</th><td class="field-body">Shows how to make a tree-structure</td>
  401. </tr>
  402. <tr class="field"><th class="field-name"><a class="reference external" href="../test/ptr_array.cpp">array_test.cpp</a>:</th><td class="field-body">Shows how to make an n-ary tree</td>
  403. </tr>
  404. </tbody>
  405. </table>
  406. </div>
  407. <div class="section" id="a-large-example">
  408. <h1><a class="toc-backref" href="#id10">9. A large example</a></h1>
  409. <p>This example shows many of the most common
  410. features at work. The example provide lots of comments.
  411. The source code can also be found <a class="reference external" href="../test/tut1.cpp">here</a>.</p>
  412. <html>
  413. <head>
  414. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  415. <title> </title>
  416. <link rel="stylesheet" href="default.css" type="text/css">
  417. </head>
  418. <body>
  419. <pre><span class=comment>//
  420. // Boost.Pointer Container
  421. //
  422. // Copyright Thorsten Ottosen 2003-2005. Use, modification and
  423. // distribution is subject to the Boost Software License, Version
  424. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  425. // http://www.boost.org/LICENSE_1_0.txt)
  426. //
  427. // For more information, see http://www.boost.org/libs/ptr_container/
  428. //
  429. //
  430. // This example is intended to get you started.
  431. // Notice how the smart container
  432. //
  433. // 1. takes ownership of objects
  434. // 2. transfers ownership
  435. // 3. applies indirection to iterators
  436. // 4. clones objects from other smart containers
  437. //
  438. //
  439. // First we select which container to use.
  440. //</span>
  441. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>ptr_container</span><span class=special>/</span><span class=identifier>ptr_deque</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
  442. <span class=comment>//
  443. // we need these later in the example
  444. //</span>
  445. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>assert</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
  446. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>string</span><span class=special>&gt;</span>
  447. <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>exception</span><span class=special>&gt;</span>
  448. <span class=comment>//
  449. // Then we define a small polymorphic class
  450. // hierarchy.
  451. //</span>
  452. <span class=keyword>class</span> <span class=identifier>animal</span> <span class=special>:</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>noncopyable</span>
  453. <span class=special>{</span>
  454. <span class=keyword>virtual</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>do_speak</span><span class=special>()</span> <span class=keyword>const</span> <span class=special>=</span> <span class=number>0</span><span class=special>;</span>
  455. <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name_</span><span class=special>;</span>
  456. <span class=keyword>protected</span><span class=special>:</span>
  457. <span class=comment>//
  458. // Animals cannot be copied...
  459. //</span>
  460. <span class=identifier>animal</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>animal</span><span class=special>&amp;</span> <span class=identifier>r</span> <span class=special>)</span> <span class=special>:</span> <span class=identifier>name_</span><span class=special>(</span> <span class=identifier>r</span><span class=special>.</span><span class=identifier>name_</span> <span class=special>)</span> <span class=special>{</span> <span class=special>}</span>
  461. <span class=keyword>void</span> <span class=keyword>operator</span><span class=special>=(</span> <span class=keyword>const</span> <span class=identifier>animal</span><span class=special>&amp;</span> <span class=special>);</span>
  462. <span class=keyword>private</span><span class=special>:</span>
  463. <span class=comment>//
  464. // ...but due to advances in genetics, we can clone them!
  465. //</span>
  466. <span class=keyword>virtual</span> <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>do_clone</span><span class=special>()</span> <span class=keyword>const</span> <span class=special>=</span> <span class=number>0</span><span class=special>;</span>
  467. <span class=keyword>public</span><span class=special>:</span>
  468. <span class=identifier>animal</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>name</span> <span class=special>)</span> <span class=special>:</span> <span class=identifier>name_</span><span class=special>(</span><span class=identifier>name</span><span class=special>)</span> <span class=special>{</span> <span class=special>}</span>
  469. <span class=keyword>virtual</span> <span class=special>~</span><span class=identifier>animal</span><span class=special>()</span> <span class=keyword>throw</span><span class=special>()</span> <span class=special>{</span> <span class=special>}</span>
  470. <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>speak</span><span class=special>()</span> <span class=keyword>const</span>
  471. <span class=special>{</span>
  472. <span class=keyword>return</span> <span class=identifier>do_speak</span><span class=special>();</span>
  473. <span class=special>}</span>
  474. <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name</span><span class=special>()</span> <span class=keyword>const</span>
  475. <span class=special>{</span>
  476. <span class=keyword>return</span> <span class=identifier>name_</span><span class=special>;</span>
  477. <span class=special>}</span>
  478. <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>clone</span><span class=special>()</span> <span class=keyword>const</span>
  479. <span class=special>{</span>
  480. <span class=keyword>return</span> <span class=identifier>do_clone</span><span class=special>();</span>
  481. <span class=special>}</span>
  482. <span class=special>};</span>
  483. <span class=comment>//
  484. // An animal is still not Clonable. We need this last hook.
  485. //
  486. // Notice that we pass the animal by const reference
  487. // and return by pointer.
  488. //</span>
  489. <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>new_clone</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>animal</span><span class=special>&amp;</span> <span class=identifier>a</span> <span class=special>)</span>
  490. <span class=special>{</span>
  491. <span class=keyword>return</span> <span class=identifier>a</span><span class=special>.</span><span class=identifier>clone</span><span class=special>();</span>
  492. <span class=special>}</span>
  493. <span class=comment>//
  494. // We do not need to define 'delete_clone()' since
  495. // since the default is to call the default 'operator delete()'.
  496. //</span>
  497. <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>muuuh</span> <span class=special>=</span> <span class=string>&quot;Muuuh!&quot;</span><span class=special>;</span>
  498. <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>oiink</span> <span class=special>=</span> <span class=string>&quot;Oiiink&quot;</span><span class=special>;</span>
  499. <span class=keyword>class</span> <span class=identifier>cow</span> <span class=special>:</span> <span class=keyword>public</span> <span class=identifier>animal</span>
  500. <span class=special>{</span>
  501. <span class=keyword>virtual</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>do_speak</span><span class=special>()</span> <span class=keyword>const</span>
  502. <span class=special>{</span>
  503. <span class=keyword>return</span> <span class=identifier>muuuh</span><span class=special>;</span>
  504. <span class=special>}</span>
  505. <span class=keyword>virtual</span> <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>do_clone</span><span class=special>()</span> <span class=keyword>const</span>
  506. <span class=special>{</span>
  507. <span class=keyword>return</span> <span class=keyword>new</span> <span class=identifier>cow</span><span class=special>(</span> <span class=special>*</span><span class=keyword>this</span> <span class=special>);</span>
  508. <span class=special>}</span>
  509. <span class=keyword>public</span><span class=special>:</span>
  510. <span class=identifier>cow</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>name</span> <span class=special>)</span> <span class=special>:</span> <span class=identifier>animal</span><span class=special>(</span><span class=identifier>name</span><span class=special>)</span> <span class=special>{</span> <span class=special>}</span>
  511. <span class=special>};</span>
  512. <span class=keyword>class</span> <span class=identifier>pig</span> <span class=special>:</span> <span class=keyword>public</span> <span class=identifier>animal</span>
  513. <span class=special>{</span>
  514. <span class=keyword>virtual</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>do_speak</span><span class=special>()</span> <span class=keyword>const</span>
  515. <span class=special>{</span>
  516. <span class=keyword>return</span> <span class=identifier>oiink</span><span class=special>;</span>
  517. <span class=special>}</span>
  518. <span class=keyword>virtual</span> <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>do_clone</span><span class=special>()</span> <span class=keyword>const</span>
  519. <span class=special>{</span>
  520. <span class=keyword>return</span> <span class=keyword>new</span> <span class=identifier>pig</span><span class=special>(</span> <span class=special>*</span><span class=keyword>this</span> <span class=special>);</span>
  521. <span class=special>}</span>
  522. <span class=keyword>public</span><span class=special>:</span>
  523. <span class=identifier>pig</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>name</span> <span class=special>)</span> <span class=special>:</span> <span class=identifier>animal</span><span class=special>(</span><span class=identifier>name</span><span class=special>)</span> <span class=special>{</span> <span class=special>}</span>
  524. <span class=special>};</span>
  525. <span class=comment>//
  526. // Then we, of course, need a place to put all
  527. // those animals.
  528. //</span>
  529. <span class=keyword>class</span> <span class=identifier>farm</span>
  530. <span class=special>{</span>
  531. <span class=comment>//
  532. // This is where the smart containers are handy
  533. //</span>
  534. <span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>ptr_deque</span><span class=special>&lt;</span><span class=identifier>animal</span><span class=special>&gt;</span> <span class=identifier>barn_type</span><span class=special>;</span>
  535. <span class=identifier>barn_type</span> <span class=identifier>barn</span><span class=special>;</span>
  536. <span class=comment>//
  537. // A convenience typedef for the compiler-appropriate
  538. // smart pointer used to manage barns
  539. //</span>
  540. <span class=keyword>typedef</span> <span class=identifier><a href="compatible_smart_ptr.html"><em>compatible-smart-ptr</em></a></span><span class=special>&lt;</span><span class=identifier>barn_type</span><span class=special>&gt;</span> <span class=identifier>raii_ptr</span><span class=special>;</span>
  541. <span class=comment>//
  542. // An error type
  543. //</span>
  544. <span class=keyword>struct</span> <span class=identifier>farm_trouble</span> <span class=special>:</span> <span class=keyword>public</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>exception</span> <span class=special>{</span> <span class=special>};</span>
  545. <span class=keyword>public</span><span class=special>:</span>
  546. <span class=comment>//
  547. // We would like to make it possible to
  548. // iterate over the animals in the farm
  549. //</span>
  550. <span class=keyword>typedef</span> <span class=identifier>barn_type</span><span class=special>::</span><span class=identifier>iterator</span> <span class=identifier>animal_iterator</span><span class=special>;</span>
  551. <span class=comment>//
  552. // We also need to count the farm's size...
  553. //</span>
  554. <span class=keyword>typedef</span> <span class=identifier>barn_type</span><span class=special>::</span><span class=identifier>size_type</span> <span class=identifier>size_type</span><span class=special>;</span>
  555. <span class=comment>//
  556. // And we also want to transfer an animal
  557. // safely around. The easiest way to think
  558. // about '::auto_type' is to imagine a simplified
  559. // 'std::auto_ptr&lt;T&gt;' ... this means you can expect
  560. //
  561. // T* operator-&gt;()
  562. // T* release()
  563. // deleting destructor
  564. //
  565. // but not more.
  566. //</span>
  567. <span class=keyword>typedef</span> <span class=identifier>barn_type</span><span class=special>::</span><span class=identifier>auto_type</span> <span class=identifier>animal_transport</span><span class=special>;</span>
  568. <span class=comment>//
  569. // Create an empty farm.
  570. //</span>
  571. <span class=identifier>farm</span><span class=special>()</span> <span class=special>{</span> <span class=special>}</span>
  572. <span class=comment>//
  573. // We need a constructor that can make a new
  574. // farm by cloning a range of animals.
  575. //</span>
  576. <span class=identifier>farm</span><span class=special>(</span> <span class=identifier>animal_iterator</span> <span class=identifier>begin</span><span class=special>,</span> <span class=identifier>animal_iterator</span> <span class=identifier>end</span> <span class=special>)</span>
  577. <span class=special>:</span>
  578. <span class=comment>//
  579. // Objects are always cloned before insertion
  580. // unless we explicitly add a pointer or
  581. // use 'release()'. Therefore we actually
  582. // clone all animals in the range
  583. //</span>
  584. <span class=identifier>barn</span><span class=special>(</span> <span class=identifier>begin</span><span class=special>,</span> <span class=identifier>end</span> <span class=special>)</span> <span class=special>{</span> <span class=special>}</span>
  585. <span class=comment>//
  586. // ... so we need some other function too
  587. //</span>
  588. <span class=identifier>animal_iterator</span> <span class=identifier>begin</span><span class=special>()</span>
  589. <span class=special>{</span>
  590. <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>begin</span><span class=special>();</span>
  591. <span class=special>}</span>
  592. <span class=identifier>animal_iterator</span> <span class=identifier>end</span><span class=special>()</span>
  593. <span class=special>{</span>
  594. <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span>
  595. <span class=special>}</span>
  596. <span class=comment>//
  597. // Here it is quite ok to have an 'animal*' argument.
  598. // The smart container will handle all ownership
  599. // issues.
  600. //</span>
  601. <span class=keyword>void</span> <span class=identifier>buy_animal</span><span class=special>(</span> <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>a</span> <span class=special>)</span>
  602. <span class=special>{</span>
  603. <span class=identifier>barn</span><span class=special>.</span><span class=identifier>push_back</span><span class=special>(</span> <span class=identifier>a</span> <span class=special>);</span>
  604. <span class=special>}</span>
  605. <span class=comment>//
  606. // The farm can also be in economical trouble and
  607. // therefore be in the need to sell animals.
  608. //</span>
  609. <span class=identifier>animal_transport</span> <span class=identifier>sell_animal</span><span class=special>(</span> <span class=identifier>animal_iterator</span> <span class=identifier>to_sell</span> <span class=special>)</span>
  610. <span class=special>{</span>
  611. <span class=keyword>if</span><span class=special>(</span> <span class=identifier>to_sell</span> <span class=special>==</span> <span class=identifier>end</span><span class=special>()</span> <span class=special>)</span>
  612. <span class=keyword>throw</span> <span class=identifier>farm_trouble</span><span class=special>();</span>
  613. <span class=comment>//
  614. // Here we remove the animal from the barn,
  615. // but the animal is not deleted yet...it's
  616. // up to the buyer to decide what
  617. // to do with it.
  618. //</span>
  619. <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>release</span><span class=special>(</span> <span class=identifier>to_sell</span> <span class=special>);</span>
  620. <span class=special>}</span>
  621. <span class=comment>//
  622. // How big a farm do we have?
  623. //</span>
  624. <span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span> <span class=keyword>const</span>
  625. <span class=special>{</span>
  626. <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>size</span><span class=special>();</span>
  627. <span class=special>}</span>
  628. <span class=comment>//
  629. // If things are bad, we might choose to sell all animals :-(
  630. //</span>
  631. <span class=identifier>raii_ptr</span> <span class=identifier>sell_farm</span><span class=special>()</span>
  632. <span class=special>{</span>
  633. <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>release</span><span class=special>();</span>
  634. <span class=special>}</span>
  635. <span class=comment>//
  636. // However, if things are good, we might buy somebody
  637. // else's farm :-)
  638. //</span>
  639. <span class=keyword>void</span> <span class=identifier>buy_farm</span><span class=special>(</span> <span class=identifier>raii_ptr</span> <span class=identifier>other</span> <span class=special>)</span>
  640. <span class=special>{</span>
  641. <span class=comment>//
  642. // This line inserts all the animals from 'other'
  643. // and is guaranteed either to succeed or to have no
  644. // effect
  645. //</span>
  646. <span class=identifier>barn</span><span class=special>.</span><span class=identifier>transfer</span><span class=special>(</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span> <span class=comment>// insert new animals at the end</span>
  647. <span class=special>*</span><span class=identifier>other</span> <span class=special>);</span> <span class=comment>// we want to transfer all animals,
  648. // so we use the whole container as argument
  649. //
  650. // You might think you would have to do
  651. //
  652. // other.release();
  653. //
  654. // but '*other' is empty and can go out of scope as it wants
  655. //</span>
  656. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>other</span><span class=special>-&gt;</span><span class=identifier>empty</span><span class=special>()</span> <span class=special>);</span>
  657. <span class=special>}</span>
  658. <span class=special>};</span> <span class=comment>// class 'farm'.</span>
  659. <span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
  660. <span class=special>{</span>
  661. <span class=comment>//
  662. // First we make a farm
  663. //</span>
  664. <span class=identifier>farm</span> <span class=identifier>animal_farm</span><span class=special>;</span>
  665. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>0u</span> <span class=special>);</span>
  666. <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>pig</span><span class=special>(</span><span class=string>&quot;Betty&quot;</span><span class=special>)</span> <span class=special>);</span>
  667. <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>pig</span><span class=special>(</span><span class=string>&quot;Benny&quot;</span><span class=special>)</span> <span class=special>);</span>
  668. <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>pig</span><span class=special>(</span><span class=string>&quot;Jeltzin&quot;</span><span class=special>)</span> <span class=special>);</span>
  669. <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>cow</span><span class=special>(</span><span class=string>&quot;Hanz&quot;</span><span class=special>)</span> <span class=special>);</span>
  670. <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>cow</span><span class=special>(</span><span class=string>&quot;Mary&quot;</span><span class=special>)</span> <span class=special>);</span>
  671. <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>cow</span><span class=special>(</span><span class=string>&quot;Frederik&quot;</span><span class=special>)</span> <span class=special>);</span>
  672. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>6u</span> <span class=special>);</span>
  673. <span class=comment>//
  674. // Then we make another farm...it will actually contain
  675. // a clone of the other farm.
  676. //</span>
  677. <span class=identifier>farm</span> <span class=identifier>new_farm</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>end</span><span class=special>()</span> <span class=special>);</span>
  678. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>6u</span> <span class=special>);</span>
  679. <span class=comment>//
  680. // Is it really clones in the new farm?
  681. //</span>
  682. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>begin</span><span class=special>()-&gt;</span><span class=identifier>name</span><span class=special>()</span> <span class=special>==</span> <span class=string>&quot;Betty&quot;</span> <span class=special>);</span>
  683. <span class=comment>//
  684. // Then we search for an animal, Mary (the Crown Princess of Denmark),
  685. // because we would like to buy her ...
  686. //</span>
  687. <span class=keyword>typedef</span> <span class=identifier>farm</span><span class=special>::</span><span class=identifier>animal_iterator</span> <span class=identifier>iterator</span><span class=special>;</span>
  688. <span class=identifier>iterator</span> <span class=identifier>to_sell</span><span class=special>;</span>
  689. <span class=keyword>for</span><span class=special>(</span> <span class=identifier>iterator</span> <span class=identifier>i</span> <span class=special>=</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span>
  690. <span class=identifier>end</span> <span class=special>=</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span>
  691. <span class=identifier>i</span> <span class=special>!=</span> <span class=identifier>end</span><span class=special>;</span> <span class=special>++</span><span class=identifier>i</span> <span class=special>)</span>
  692. <span class=special>{</span>
  693. <span class=keyword>if</span><span class=special>(</span> <span class=identifier>i</span><span class=special>-&gt;</span><span class=identifier>name</span><span class=special>()</span> <span class=special>==</span> <span class=string>&quot;Mary&quot;</span> <span class=special>)</span>
  694. <span class=special>{</span>
  695. <span class=identifier>to_sell</span> <span class=special>=</span> <span class=identifier>i</span><span class=special>;</span>
  696. <span class=keyword>break</span><span class=special>;</span>
  697. <span class=special>}</span>
  698. <span class=special>}</span>
  699. <span class=identifier>farm</span><span class=special>::</span><span class=identifier>animal_transport</span> <span class=identifier>mary</span> <span class=special>=</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>sell_animal</span><span class=special>(</span> <span class=identifier>to_sell</span> <span class=special>);</span>
  700. <span class=keyword>if</span><span class=special>(</span> <span class=identifier>mary</span><span class=special>-&gt;</span><span class=identifier>speak</span><span class=special>()</span> <span class=special>==</span> <span class=identifier>muuuh</span> <span class=special>)</span>
  701. <span class=comment>//
  702. // Great, Mary is a cow, and she may live longer
  703. //</span>
  704. <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=identifier>mary</span><span class=special>.</span><span class=identifier>release</span><span class=special>()</span> <span class=special>);</span>
  705. <span class=keyword>else</span>
  706. <span class=comment>//
  707. // Then the animal would be destroyed (!)
  708. // when we go out of scope.
  709. //</span>
  710. <span class=special>;</span>
  711. <span class=comment>//
  712. // Now we can observe some changes to the two farms...
  713. //</span>
  714. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>5u</span> <span class=special>);</span>
  715. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>7u</span> <span class=special>);</span>
  716. <span class=comment>//
  717. // The new farm has however underestimated how much
  718. // it cost to feed Mary and its owner is forced to sell the farm...
  719. //</span>
  720. <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_farm</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>sell_farm</span><span class=special>()</span> <span class=special>);</span>
  721. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>0u</span> <span class=special>);</span>
  722. <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>12u</span> <span class=special>);</span>
  723. <span class=special>}</span>
  724. </pre>
  725. </body>
  726. </html>
  727. <!-- 10. Changing the Clone Allocator
  728. ++++++++++++++++++++++++++++++++
  729. This example shows how we can change
  730. the Clone Allocator to use the pointer containers
  731. as view into other containers:
  732. .. raw:: html
  733. :file: tut2.html -->
  734. <hr><p><strong>Navigate:</strong></p>
  735. <ul class="simple">
  736. <li><a class="reference external" href="ptr_container.html">home</a></li>
  737. <li><a class="reference external" href="reference.html">reference</a></li>
  738. </ul>
  739. <hr><table class="docutils field-list" frame="void" rules="none">
  740. <col class="field-name" />
  741. <col class="field-body" />
  742. <tbody valign="top">
  743. <tr class="field"><th class="field-name">Copyright:</th><td class="field-body">Thorsten Ottosen 2004-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see <a class="reference external" href="http://www.boost.org/LICENSE_1_0.txt">LICENSE_1_0.txt</a>).</td>
  744. </tr>
  745. </tbody>
  746. </table>
  747. </div>
  748. </div>
  749. </body>
  750. </html>