1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Any Hooks: A single hook for any Intrusive container</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../intrusive.html" title="Chapter 15. Boost.Intrusive">
<link rel="prev" href="obtaining_iterators_from_values.html" title="Obtaining iterators from values">
<link rel="next" href="concepts.html" title="Concepts explained">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="obtaining_iterators_from_values.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../intrusive.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="concepts.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="intrusive.any_hooks"></a><a class="link" href="any_hooks.html" title="Any Hooks: A single hook for any Intrusive container">Any Hooks: A single hook for any Intrusive
container</a>
</h2></div></div></div>
<p>
Sometimes, a class programmer wants to place a class in several intrusive containers
but no at the same time. In this case, the programmer might decide to insert
two hooks in the same class.
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">MyClass</span>
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">list_base_hook</span><span class="special"><>,</span> <span class="keyword">public</span> <span class="identifier">slist_base_hook</span><span class="special"><></span> <span class="comment">//...</span>
<span class="special">{};</span>
</pre>
<p>
However, there is a more size-efficient alternative in <span class="bold"><strong>Boost.Intrusive</strong></span>:
"any" hooks (<code class="computeroutput"><a class="link" href="../boost/intrusive/any_base_hook.html" title="Class template any_base_hook">any_base_hook</a></code>
and <code class="computeroutput"><a class="link" href="../boost/intrusive/any_member_hook.html" title="Class template any_member_hook">any_member_hook</a></code>).
These hooks can be used to store a type in several containers offered by <span class="bold"><strong>Boost.Intrusive</strong></span> minimizing the size of the class.
</p>
<p>
These hooks support these options:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong><code class="computeroutput"><span class="identifier">tag</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Tag</span><span class="special">></span></code></strong></span>
(for base hooks only): This argument serves as a tag, so you can derive
from more than one slist hook. Default: <code class="computeroutput"><span class="identifier">tag</span><span class="special"><</span><span class="identifier">default_tag</span><span class="special">></span></code>.
</li>
<li class="listitem">
<span class="bold"><strong><code class="computeroutput"><span class="identifier">link_mode</span><span class="special"><</span><span class="identifier">link_mode_type</span>
<span class="identifier">LinkMode</span><span class="special">></span></code></strong></span>:
The linking policy. <code class="computeroutput"><span class="identifier">link_mode</span><span class="special"><</span><span class="identifier">auto_unlink</span><span class="special">></span></code> is <span class="bold"><strong>not</strong></span>
supported and <code class="computeroutput"><span class="identifier">link_mode</span><span class="special"><</span><span class="identifier">safe_mode</span><span class="special">></span></code> might offer weaker error detection
in any hooks than in other hooks. Default: <code class="computeroutput"><span class="identifier">link_mode</span><span class="special"><</span><span class="identifier">safe_link</span><span class="special">></span></code>.
</li>
<li class="listitem">
<span class="bold"><strong><code class="computeroutput"><span class="identifier">void_pointer</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">VoidPointer</span><span class="special">></span></code></strong></span>:
The pointer type to be used internally in the hook and propagated to the
container. Default: <code class="computeroutput"><span class="identifier">void_pointer</span><span class="special"><</span><span class="keyword">void</span><span class="special">*></span></code>.
</li>
</ul></div>
<p>
<code class="computeroutput"><span class="identifier">auto_unlink</span></code> can't be supported
because the hook does not know in which type of container might be currently
inserted. Additionally, these hooks don't support <code class="computeroutput"><span class="identifier">unlink</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">swap_nodes</span><span class="special">()</span></code> operations for the same reason.
</p>
<p>
Here is an example that creates a class with two any hooks, and uses one to
insert the class in a <code class="computeroutput">slist</code> and the other
one in a <code class="computeroutput">list</code>.
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span>
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">intrusive</span><span class="special">/</span><span class="identifier">any_hook</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">intrusive</span><span class="special">/</span><span class="identifier">slist</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">intrusive</span><span class="special">/</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">intrusive</span><span class="special">;</span>
<span class="keyword">class</span> <span class="identifier">MyClass</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">any_base_hook</span><span class="special"><></span> <span class="comment">//Base hook</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">int_</span><span class="special">;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">any_member_hook</span><span class="special"><></span> <span class="identifier">member_hook_</span><span class="special">;</span> <span class="comment">//Member hook</span>
<span class="identifier">MyClass</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">int_</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span>
<span class="special">{}</span>
<span class="special">};</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">//Define a base hook option that converts any_base_hook to a slist hook</span>
<span class="keyword">typedef</span> <span class="identifier">any_to_slist_hook</span> <span class="special"><</span> <span class="identifier">base_hook</span><span class="special"><</span> <span class="identifier">any_base_hook</span><span class="special"><></span> <span class="special">></span> <span class="special">></span> <span class="identifier">BaseSlistOption</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">slist</span><span class="special"><</span><span class="identifier">MyClass</span><span class="special">,</span> <span class="identifier">BaseSlistOption</span><span class="special">></span> <span class="identifier">BaseSList</span><span class="special">;</span>
<span class="comment">//Define a member hook option that converts any_member_hook to a list hook</span>
<span class="keyword">typedef</span> <span class="identifier">any_to_list_hook</span><span class="special"><</span> <span class="identifier">member_hook</span>
<span class="special"><</span> <span class="identifier">MyClass</span><span class="special">,</span> <span class="identifier">any_member_hook</span><span class="special"><>,</span> <span class="special">&</span><span class="identifier">MyClass</span><span class="special">::</span><span class="identifier">member_hook_</span><span class="special">></span> <span class="special">></span> <span class="identifier">MemberListOption</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">list</span><span class="special"><</span><span class="identifier">MyClass</span><span class="special">,</span> <span class="identifier">MemberListOption</span><span class="special">></span> <span class="identifier">MemberList</span><span class="special">;</span>
<span class="comment">//Create several MyClass objects, each one with a different value</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">MyClass</span><span class="special">></span> <span class="identifier">values</span><span class="special">;</span>
<span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="number">100</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">){</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">MyClass</span><span class="special">(</span><span class="identifier">i</span><span class="special">));</span> <span class="special">}</span>
<span class="identifier">BaseSList</span> <span class="identifier">base_slist</span><span class="special">;</span> <span class="identifier">MemberList</span> <span class="identifier">member_list</span><span class="special">;</span>
<span class="comment">//Now insert them in reverse order in the slist and in order in the list</span>
<span class="keyword">for</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">MyClass</span><span class="special">>::</span><span class="identifier">iterator</span> <span class="identifier">it</span><span class="special">(</span><span class="identifier">values</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()),</span> <span class="identifier">itend</span><span class="special">(</span><span class="identifier">values</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">itend</span><span class="special">;</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span>
<span class="identifier">base_slist</span><span class="special">.</span><span class="identifier">push_front</span><span class="special">(*</span><span class="identifier">it</span><span class="special">),</span> <span class="identifier">member_list</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(*</span><span class="identifier">it</span><span class="special">);</span>
<span class="comment">//Now test lists</span>
<span class="identifier">BaseSList</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">bit</span><span class="special">(</span><span class="identifier">base_slist</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>
<span class="identifier">MemberList</span><span class="special">::</span><span class="identifier">reverse_iterator</span> <span class="identifier">mrit</span><span class="special">(</span><span class="identifier">member_list</span><span class="special">.</span><span class="identifier">rbegin</span><span class="special">());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">MyClass</span><span class="special">>::</span><span class="identifier">reverse_iterator</span> <span class="identifier">rit</span><span class="special">(</span><span class="identifier">values</span><span class="special">.</span><span class="identifier">rbegin</span><span class="special">()),</span> <span class="identifier">ritend</span><span class="special">(</span><span class="identifier">values</span><span class="special">.</span><span class="identifier">rend</span><span class="special">());</span>
<span class="comment">//Test the objects inserted in the base hook list</span>
<span class="keyword">for</span><span class="special">(;</span> <span class="identifier">rit</span> <span class="special">!=</span> <span class="identifier">ritend</span><span class="special">;</span> <span class="special">++</span><span class="identifier">rit</span><span class="special">,</span> <span class="special">++</span><span class="identifier">bit</span><span class="special">,</span> <span class="special">++</span><span class="identifier">mrit</span><span class="special">)</span>
<span class="keyword">if</span><span class="special">(&*</span><span class="identifier">bit</span> <span class="special">!=</span> <span class="special">&*</span><span class="identifier">rit</span> <span class="special">||</span> <span class="special">&*</span><span class="identifier">mrit</span> <span class="special">!=</span> <span class="special">&*</span><span class="identifier">rit</span><span class="special">)</span> <span class="keyword">return</span> <span class="number">1</span><span class="special">;</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2005 Olaf Krzikalla<br>Copyright © 2006-2013 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="obtaining_iterators_from_values.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../intrusive.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="concepts.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
|