• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Concepts explained</title>
6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="../intrusive.html" title="Chapter 19. Boost.Intrusive">
10<link rel="prev" href="any_hooks.html" title="Any Hooks: A single hook for any Intrusive container">
11<link rel="next" href="node_algorithms.html" title="Node algorithms with custom NodeTraits">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16<td align="center"><a href="../../../index.html">Home</a></td>
17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<a accesskey="p" href="any_hooks.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="node_algorithms.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
25</div>
26<div class="section">
27<div class="titlepage"><div><div><h2 class="title" style="clear: both">
28<a name="intrusive.concepts"></a><a class="link" href="concepts.html" title="Concepts explained">Concepts explained</a>
29</h2></div></div></div>
30<p>
31      This section will expand the explanation of previously presented basic concepts
32      before explaining the customization options of <span class="bold"><strong>Boost.Intrusive</strong></span>.
33    </p>
34<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
35          <span class="bold"><strong>Node Algorithms</strong></span>: A set of static functions
36          that implement basic operations on a group of nodes: initialize a node,
37          link a node to a group of nodes, unlink a node from another group of nodes,
38          etc. For example, a circular singly linked list is a group of nodes, where
39          each node has a pointer to the next node. <span class="bold"><strong>Node Algorithms</strong></span>
40          just require a <span class="bold"><strong>NodeTraits</strong></span> template parameter
41          and they can work with any <span class="bold"><strong>NodeTraits</strong></span>
42          class that fulfills the needed interface. As an example, here is a class
43          that implements operations to manage a group of nodes forming a circular
44          singly linked list:
45        </li></ul></div>
46<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">NodeTraits</span><span class="special">&gt;</span>
47<span class="keyword">struct</span> <span class="identifier">my_slist_algorithms</span>
48<span class="special">{</span>
49   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">NodeTraits</span><span class="special">::</span><span class="identifier">node_ptr</span>       <span class="identifier">node_ptr</span><span class="special">;</span>
50   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">NodeTraits</span><span class="special">::</span><span class="identifier">const_node_ptr</span> <span class="identifier">const_node_ptr</span><span class="special">;</span>
51
52   <span class="comment">//Get the previous node of "this_node"</span>
53   <span class="keyword">static</span> <span class="identifier">node_ptr</span> <span class="identifier">get_prev_node</span><span class="special">(</span><span class="identifier">node_ptr</span> <span class="identifier">this_node</span><span class="special">)</span>
54   <span class="special">{</span>
55      <span class="identifier">node_ptr</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">this_node</span><span class="special">;</span>
56      <span class="keyword">while</span> <span class="special">(</span><span class="identifier">this_node</span> <span class="special">!=</span> <span class="identifier">NodeTraits</span><span class="special">::</span><span class="identifier">get_next</span><span class="special">(</span><span class="identifier">p</span><span class="special">))</span>
57         <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">NodeTraits</span><span class="special">::</span><span class="identifier">get_next</span><span class="special">(</span><span class="identifier">p</span><span class="special">);</span>
58      <span class="keyword">return</span> <span class="identifier">p</span><span class="special">;</span>
59   <span class="special">}</span>
60
61   <span class="comment">// number of elements in the group of nodes containing "this_node"</span>
62   <span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">(</span><span class="identifier">const_node_ptr</span> <span class="identifier">this_node</span><span class="special">)</span>
63   <span class="special">{</span>
64      <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">result</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
65      <span class="identifier">const_node_ptr</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">this_node</span><span class="special">;</span>
66      <span class="keyword">do</span><span class="special">{</span>
67         <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">NodeTraits</span><span class="special">::</span><span class="identifier">get_next</span><span class="special">(</span><span class="identifier">p</span><span class="special">);</span>
68         <span class="special">++</span><span class="identifier">result</span><span class="special">;</span>
69      <span class="special">}</span> <span class="keyword">while</span> <span class="special">(</span><span class="identifier">p</span> <span class="special">!=</span> <span class="identifier">this_node</span><span class="special">);</span>
70      <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
71   <span class="special">}</span>
72
73   <span class="comment">// More operations</span>
74   <span class="comment">// ...</span>
75<span class="special">};</span>
76</pre>
77<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
78          <span class="bold"><strong>Node Traits</strong></span>: A class that encapsulates
79          the basic information and operations on a node within a group of nodes:
80          the type of the node, a function to obtain the pointer to the next node,
81          etc. <span class="bold"><strong>Node Traits</strong></span> specify the configuration
82          information <span class="bold"><strong>Node Algorithms</strong></span> need. Each
83          type of <span class="bold"><strong>Node Algorithm</strong></span> expects an interface
84          that compatible <span class="bold"><strong>Node Traits</strong></span> classes must
85          implement. As an example, this is the definition of a <span class="bold"><strong>Node
86          Traits</strong></span> class that is compatible with the previously presented
87          <code class="computeroutput"><span class="identifier">my_slist_algorithms</span></code>:
88        </li></ul></div>
89<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_slist_node_traits</span>
90<span class="special">{</span>
91   <span class="comment">//The type of the node</span>
92   <span class="keyword">struct</span> <span class="identifier">node</span>
93   <span class="special">{</span>
94      <span class="identifier">node</span> <span class="special">*</span><span class="identifier">next_</span><span class="special">;</span>
95   <span class="special">};</span>
96
97   <span class="keyword">typedef</span> <span class="identifier">node</span> <span class="special">*</span>       <span class="identifier">node_ptr</span><span class="special">;</span>
98   <span class="keyword">typedef</span> <span class="keyword">const</span> <span class="identifier">node</span> <span class="special">*</span> <span class="identifier">const_node_ptr</span><span class="special">;</span>
99
100   <span class="comment">//A function to obtain a pointer to the next node</span>
101   <span class="keyword">static</span> <span class="identifier">node_ptr</span> <span class="identifier">get_next</span><span class="special">(</span><span class="identifier">const_node_ptr</span> <span class="identifier">n</span><span class="special">)</span>
102   <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">n</span><span class="special">-&gt;</span><span class="identifier">next_</span><span class="special">;</span>  <span class="special">}</span>
103
104   <span class="comment">//A function to set the pointer to the next node</span>
105   <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">set_next</span><span class="special">(</span><span class="identifier">node_ptr</span> <span class="identifier">n</span><span class="special">,</span> <span class="identifier">node_ptr</span> <span class="identifier">next</span><span class="special">)</span>
106   <span class="special">{</span>  <span class="identifier">n</span><span class="special">-&gt;</span><span class="identifier">next_</span> <span class="special">=</span> <span class="identifier">next</span><span class="special">;</span>  <span class="special">}</span>
107<span class="special">};</span>
108</pre>
109<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
110          <span class="bold"><strong>Hook</strong></span>: A class that the user must add as
111          a base class or as a member to his own class to make that class insertable
112          in an intrusive container. Usually the hook contains a node object that
113          will be used to form the group of nodes: For example, the following class
114          is a <span class="bold"><strong>Hook</strong></span> that the user can add as a base
115          class, to make the user class compatible with a singly linked list container:
116        </li></ul></div>
117<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_slist_base_hook</span>
118      <span class="comment">//This hook contains a node, that will be used</span>
119      <span class="comment">//to link the user object in the group of nodes</span>
120   <span class="special">:</span> <span class="keyword">private</span> <span class="identifier">my_slist_node_traits</span><span class="special">::</span><span class="identifier">node</span>
121<span class="special">{</span>
122   <span class="keyword">typedef</span> <span class="identifier">my_slist_node_traits</span><span class="special">::</span><span class="identifier">node_ptr</span>       <span class="identifier">node_ptr</span><span class="special">;</span>
123   <span class="keyword">typedef</span> <span class="identifier">my_slist_node_traits</span><span class="special">::</span><span class="identifier">const_node_ptr</span> <span class="identifier">const_node_ptr</span><span class="special">;</span>
124
125   <span class="comment">//Converts the generic node to the hook</span>
126   <span class="keyword">static</span> <span class="identifier">my_slist_base_hook</span> <span class="special">*</span><span class="identifier">to_hook_ptr</span><span class="special">(</span><span class="identifier">node_ptr</span> <span class="identifier">p</span><span class="special">)</span>
127   <span class="special">{</span>  <span class="keyword">return</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">my_slist_base_hook</span><span class="special">*&gt;(</span><span class="identifier">p</span><span class="special">);</span> <span class="special">}</span>
128
129   <span class="comment">//Returns the generic node stored by this hook</span>
130   <span class="identifier">node_ptr</span> <span class="identifier">to_node_ptr</span><span class="special">()</span>
131   <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">node</span> <span class="special">*</span><span class="keyword">const</span><span class="special">&gt;(</span><span class="keyword">this</span><span class="special">);</span> <span class="special">}</span>
132
133   <span class="comment">// More operations</span>
134   <span class="comment">// ...</span>
135<span class="special">};</span>
136
137<span class="comment">//To make MyClass compatible with an intrusive singly linked list</span>
138<span class="comment">//derive our class from the hook.</span>
139<span class="keyword">class</span> <span class="identifier">MyClass</span>
140   <span class="special">:</span>  <span class="keyword">public</span> <span class="identifier">my_slist_base_hook</span>
141<span class="special">{</span>
142   <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">value</span><span class="special">);</span>
143   <span class="keyword">int</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
144
145   <span class="keyword">private</span><span class="special">:</span>
146   <span class="keyword">int</span> <span class="identifier">value_</span><span class="special">;</span>
147<span class="special">};</span>
148</pre>
149<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
150          <span class="bold"><strong>Intrusive Container</strong></span>: A container that
151          offers a STL-like interface to store user objects. An intrusive container
152          can be templatized to store different value types that use different hooks.
153          An intrusive container is also more elaborate than a group of nodes: it
154          can store the number of elements to achieve constant-time size information,
155          it can offer debugging facilities, etc. For example, an <code class="computeroutput"><a class="link" href="../boost/intrusive/slist.html" title="Class template slist">slist</a></code>
156          container (intrusive singly linked list) should be able to hold <code class="computeroutput"><span class="identifier">MyClass</span></code> objects that might have decided
157          to store the hook as a base class or as a member. Internally, the container
158          will use <span class="bold"><strong>Node Algorithms</strong></span> to implement
159          its operations, and an intrusive container is configured using a template
160          parameter called <span class="bold"><strong>ValueTraits</strong></span>. <span class="bold"><strong>ValueTraits</strong></span> will contain the information to convert
161          user classes in nodes compatible with <span class="bold"><strong>Node Algorithms</strong></span>.
162          For example, this a possible <code class="computeroutput"><a class="link" href="../boost/intrusive/slist.html" title="Class template slist">slist</a></code>
163          implementation:
164        </li></ul></div>
165<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ValueTraits</span><span class="special">,</span> <span class="special">...&gt;</span>
166<span class="keyword">class</span> <span class="identifier">slist</span>
167<span class="special">{</span>
168   <span class="keyword">public</span><span class="special">:</span>
169   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">ValueTraits</span><span class="special">::</span><span class="identifier">value_type</span> <span class="identifier">value_type</span><span class="special">;</span>
170
171   <span class="comment">//More typedefs and functions</span>
172   <span class="comment">// ...</span>
173
174   <span class="comment">//Insert the value as the first element of the list</span>
175   <span class="keyword">void</span> <span class="identifier">push_front</span> <span class="special">(</span><span class="identifier">reference</span> <span class="identifier">value</span><span class="special">)</span>
176   <span class="special">{</span>
177      <span class="identifier">node_ptr</span> <span class="identifier">to_insert</span><span class="special">(</span><span class="identifier">ValueTraits</span><span class="special">::</span><span class="identifier">to_node_ptr</span><span class="special">(</span><span class="identifier">value</span><span class="special">));</span>
178      <span class="identifier">circular_list_algorithms</span><span class="special">::</span><span class="identifier">link_after</span><span class="special">(</span><span class="identifier">to_insert</span><span class="special">,</span> <span class="identifier">get_root_node</span><span class="special">());</span>
179   <span class="special">}</span>
180
181   <span class="comment">// More operations</span>
182   <span class="comment">// ...</span>
183<span class="special">};</span>
184</pre>
185<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
186<li class="listitem">
187          <span class="bold"><strong>Semi-Intrusive Container</strong></span>: A semi-intrusive
188          container is similar to an intrusive container, but apart from the values
189          to be inserted in the container, it needs additional memory (for example,
190          auxiliary arrays or indexes).
191        </li>
192<li class="listitem">
193          <span class="bold"><strong>Value Traits</strong></span>: As we can see, to make our
194          classes intrusive-friendly we add a simple hook as a member or base class.
195          The hook contains a generic node that will be inserted in a group of nodes.
196          <span class="bold"><strong>Node Algorithms</strong></span> just work with nodes and
197          don't know anything about user classes. On the other hand, an intrusive
198          container needs to know how to obtain a node from a user class, and also
199          the inverse operation. So we can define <span class="bold"><strong>ValueTraits</strong></span>
200          as the glue between user classes and nodes required by <span class="bold"><strong>Node
201          Algorithms</strong></span>. Let's see a possible implementation of a value traits
202          class that glues MyClass and the node stored in the hook:
203        </li>
204</ul></div>
205<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_slist_derivation_value_traits</span>
206<span class="special">{</span>
207   <span class="keyword">public</span><span class="special">:</span>
208   <span class="keyword">typedef</span> <span class="identifier">slist_node_traits</span>           <span class="identifier">node_traits</span><span class="special">;</span>
209   <span class="keyword">typedef</span> <span class="identifier">MyClass</span>                     <span class="identifier">value_type</span><span class="special">;</span>
210   <span class="keyword">typedef</span> <span class="identifier">node_traits</span><span class="special">::</span><span class="identifier">node_ptr</span>       <span class="identifier">node_ptr</span><span class="special">;</span>
211   <span class="keyword">typedef</span> <span class="identifier">value_type</span><span class="special">*</span>                 <span class="identifier">pointer</span><span class="special">;</span>
212   <span class="comment">//...</span>
213
214   <span class="comment">//Converts user's value to a generic node</span>
215   <span class="keyword">static</span> <span class="identifier">node_ptr</span> <span class="identifier">to_node_ptr</span><span class="special">(</span><span class="identifier">reference</span> <span class="identifier">value</span><span class="special">)</span>
216   <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">slist_base_hook</span> <span class="special">&amp;&gt;(</span><span class="identifier">value</span><span class="special">).</span><span class="identifier">to_node_ptr</span><span class="special">();</span> <span class="special">}</span>
217
218   <span class="comment">//Converts a generic node into user's value</span>
219   <span class="keyword">static</span> <span class="identifier">value_type</span> <span class="special">*</span><span class="identifier">to_value_ptr</span><span class="special">(</span><span class="identifier">node_traits</span><span class="special">::</span><span class="identifier">node</span> <span class="special">*</span><span class="identifier">n</span><span class="special">)</span>
220   <span class="special">{</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">value_type</span><span class="special">*&gt;(</span><span class="identifier">slist_base_hook</span><span class="special">::</span><span class="identifier">to_hook_ptr</span><span class="special">(</span><span class="identifier">n</span><span class="special">));</span> <span class="special">}</span>
221
222   <span class="comment">// More operations</span>
223   <span class="comment">// ...</span>
224<span class="special">};</span>
225</pre>
226</div>
227<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
228<td align="left"></td>
229<td align="right"><div class="copyright-footer">Copyright © 2005 Olaf Krzikalla<br>Copyright © 2006-2015 Ion Gaztanaga<p>
230        Distributed under the Boost Software License, Version 1.0. (See accompanying
231        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>)
232      </p>
233</div></td>
234</tr></table>
235<hr>
236<div class="spirit-nav">
237<a accesskey="p" href="any_hooks.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="node_algorithms.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
238</div>
239</body>
240</html>
241