]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multi_index/doc/tutorial/debug.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / multi_index / doc / tutorial / debug.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
2
3 <html>
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
6 <title>Boost.MultiIndex Documentation - Tutorial -Debugging support</title>
7 <link rel="stylesheet" href="../style.css" type="text/css">
8 <link rel="start" href="../index.html">
9 <link rel="prev" href="creation.html">
10 <link rel="up" href="index.html">
11 <link rel="next" href="techniques.html">
12 </head>
13
14 <body>
15 <h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
16 "middle" width="277" height="86">Boost.MultiIndex Tutorial: Debugging support</h1>
17
18 <div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br>
19 Container creation
20 </a></div>
21 <div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
22 Boost.MultiIndex tutorial
23 </a></div>
24 <div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br>
25 Techniques
26 </a></div><br clear="all" style="clear: all;">
27
28 <hr>
29
30 <h2>Contents</h2>
31
32 <ul>
33 <li><a href="#debugging_support">Debugging support</a></li>
34 <li><a href="#safe_mode">Safe mode</a>
35 <ul>
36 <li><a href="#serialization_and_safe_mode">Serialization and safe mode</a></li>
37 </ul>
38 </li>
39 <li><a href="#invariant_check">Invariant-checking mode</a></li>
40 </ul>
41
42 <h2><a name="debugging_support">Debugging support</a></h2>
43
44 <p>
45 The concept of <i>Design by Contract</i>, originally developed as part
46 of Bertrand Meyer's <a href="http://www.eiffel.com">Eiffel</a> language,
47 revolves around the formulation of a <i>contract</i> between the user
48 of a library and the implementor, by which the first is required to
49 respect some <i>preconditions</i> on the values passed when invoking
50 methods of the library, and the implementor guarantees in return
51 that certain constraints on the results are met (<i>postconditions</i>),
52 as well as the honoring of specified internal consistency rules, called
53 <i>invariants</i>. Eiffel natively supports the three parts of the
54 contract just described by means of constructs <code>require</code>,
55 <code>ensure</code> and <code>invariant</code>, respectively.
56 </p>
57
58 <p>
59 C++ does not enjoy direct support for Design by Contract techniques: these
60 are customarily implemented as assertion code, often turned off in
61 release mode for performance reasons. Following this approach,
62 Boost.MultiIndex provides two distinct debugging modes:
63 <ul>
64 <li><i>Safe mode</i> checks preconditions on the invocations to the
65 facilities of the library,</li>
66 <li><i>invariant-checking mode</i> performs post-execution checks aimed
67 at ensuring that the internal consistency of the library is preserved.</li>
68 </ul>
69 These two modes are independent of each other and can be set on or off
70 individually. It is important to note that errors detected by safe mode are
71 due in principle to faulty code in the user's program, while
72 invariant-checking mode detects potential <i>internal</i> bugs in the
73 implementation of Boost.MultiIndex.
74 </p>
75
76 <h2><a name="safe_mode">Safe mode</a></h2>
77
78 <p>
79 The idea of adding precondition checking facilities to STL as a debugging aid
80 was first introduced by Cay S. Horstmann in his
81 <a href="http://www.horstmann.com/safestl.html">Safe STL</a> library and later
82 adopted by <a href="http://www.stlport.com/doc/debug_mode.html">STLport Debug
83 Mode</a>. Similarly, Boost.MultiIndex features the so-called <i>safe mode</i>
84 in which all sorts of preconditions are checked when dealing with iterators
85 and functions of the library.
86 </p>
87
88 <p>
89 Boost.MultiIndex safe mode is set by globally defining the macro
90 <code>BOOST_MULTI_INDEX_ENABLE_SAFE_MODE</code>. Error conditions
91 are checked via the macro <code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, which
92 by default resolves to a call to <a href="../../../../libs/assert/assert.html">
93 <code>BOOST_ASSERT</code></a>.
94 </p>
95
96 <p>
97 If the user decides to define her own version of
98 <code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, it has to take the form
99 </p>
100
101 <blockquote><pre>
102 <span class=identifier>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</span><span class=special>(</span><span class=identifier>expr</span><span class=special>,</span><span class=identifier>error_code</span><span class=special>)</span>
103 </pre></blockquote>
104
105 <p>
106 where <code>expr</code> is the condition checked and <code>error_code</code>
107 is one value of the <code>safe_mode::error_code</code> enumeration:
108 </p>
109
110 <blockquote><pre>
111 <span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
112
113 <span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
114
115 <span class=keyword>namespace</span> <span class=identifier>safe_mode</span><span class=special>{</span>
116
117 <span class=keyword>enum</span> <span class=identifier>error_code</span>
118 <span class=special>{</span>
119 <span class=identifier>invalid_iterator</span><span class=special>,</span> <span class=comment>// vg. default cted or pointing to erased element</span>
120 <span class=identifier>not_dereferenceable_iterator</span><span class=special>,</span> <span class=comment>// iterator is not dereferenceable</span>
121 <span class=identifier>not_incrementable_iterator</span><span class=special>,</span> <span class=comment>// iterator points to end of sequence</span>
122 <span class=identifier>not_decrementable_iterator</span><span class=special>,</span> <span class=comment>// iterator points to beginning of sequence</span>
123 <span class=identifier>not_owner</span><span class=special>,</span> <span class=comment>// iterator does not belong to the container</span>
124 <span class=identifier>not_same_owner</span><span class=special>,</span> <span class=comment>// iterators belong to different containers</span>
125 <span class=identifier>invalid_range</span><span class=special>,</span> <span class=comment>// last not reachable from first</span>
126 <span class=identifier>inside_range</span><span class=special>,</span> <span class=comment>// iterator lies within a range (and it mustn't)</span>
127 <span class=identifier>out_of_bounds</span><span class=special>,</span> <span class=comment>// move attempted beyond container limits</span>
128 <span class=identifier>same_container</span> <span class=comment>// containers ought to be different</span>
129 <span class=special>};</span>
130
131 <span class=special>}</span> <span class=comment>// namespace multi_index::safe_mode</span>
132
133 <span class=special>}</span> <span class=comment>// namespace multi_index</span>
134
135 <span class=special>}</span> <span class=comment>// namespace boost</span>
136 </pre></blockquote>
137
138 <p>
139 For instance, the following replacement of
140 <code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code> throws an exception instead of
141 asserting:
142 </p>
143
144 <blockquote><pre>
145 <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>/</span><span class=identifier>safe_mode_errors</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
146
147 <span class=keyword>struct</span> <span class=identifier>safe_mode_exception</span>
148 <span class=special>{</span>
149 <span class=identifier>safe_mode_exception</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>safe_mode</span><span class=special>::</span><span class=identifier>error_code</span> <span class=identifier>error_code</span><span class=special>):</span>
150 <span class=identifier>error_code</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>)</span>
151 <span class=special>{}</span>
152
153 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>safe_mode</span><span class=special>::</span><span class=identifier>error_code</span> <span class=identifier>error_code</span><span class=special>;</span>
154 <span class=special>};</span>
155
156 <span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</span><span class=special>(</span><span class=identifier>expr</span><span class=special>,</span><span class=identifier>error_code</span><span class=special>)</span> <span class=special>\</span>
157 <span class=keyword>if</span><span class=special>(!(</span><span class=identifier>expr</span><span class=special>)){</span><span class=keyword>throw</span> <span class=identifier>safe_mode_exception</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>);}</span>
158
159 <span class=comment>// This has to go before the inclusion of any header from Boost.MultiIndex,
160 // except possibly safe_error_codes.hpp.</span>
161 </pre></blockquote>
162
163 <p>
164 Other possibilites, like outputting to a log or firing some kind of alert, are
165 also implementable.
166 </p>
167
168 <p>
169 <b>Warning:</b> Safe mode adds a very important overhead to the program
170 both in terms of space and time used, so in general it should not be set for
171 <code>NDEBUG</code> builds. Also, this mode is intended solely as a debugging aid,
172 and programs must not rely on it as part of their normal execution flow: in
173 particular, no guarantee is made that all possible precondition errors are diagnosed,
174 or that the checks remain stable across different versions of the library.
175 </p>
176
177 <h3><a name="serialization_and_safe_mode">Serialization and safe mode</a></h3>
178
179 <p>
180 Iterators restored from an archive are not subject to safe mode checks. This is
181 so because it is not possible to automatically know the associated
182 <code>multi_index_container</code> of an iterator from the serialization
183 information alone. However, if desired, a restored iterator can be converted to a
184 checked value by using the following workaround:
185 </p>
186
187 <blockquote><pre>
188 <span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
189 <span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>;</span>
190
191 <span class=comment>// restore es and it from an archive ar</span>
192 <span class=identifier>ar</span><span class=special>&gt;&gt;</span><span class=identifier>es</span><span class=special>;</span>
193 <span class=identifier>ar</span><span class=special>&gt;&gt;</span><span class=identifier>it</span><span class=special>;</span> <span class=comment>// it won't benefit from safe mode checks
194
195 // Turn it into a checked value by providing Boost.MultiIndex
196 // with info about the associated container.
197 // This statement has virtually zero cost if safe mode is turned off.</span>
198 <span class=identifier>it</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>project</span><span class=special>&lt;</span><span class=number>1</span><span class=special>&gt;(</span><span class=identifier>it</span><span class=special>);</span>
199 </pre></blockquote>
200
201 <h2><a name="invariant_check">Invariant-checking mode</a></h2>
202
203 <p>
204 The so called <i>invariant-checking mode</i> of Boost.MultiIndex can be
205 set by globally defining the macro
206 <code>BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING</code>.
207 When this mode is in effect, all public functions of Boost.MultiIndex
208 will perform post-execution tests aimed at ensuring that the basic
209 internal invariants of the data structures managed are preserved.
210 </p>
211
212 <p>
213 If an invariant test fails, Boost.MultiIndex will indicate the failure
214 by means of the unary macro <code>BOOST_MULTI_INDEX_INVARIANT_ASSERT</code>.
215 Unless the user provides a definition for this macro, it defaults to
216 <a href="../../../../libs/assert/assert.html">
217 <code>BOOST_ASSERT</code></a>. Any assertion of this kind should
218 be regarded in principle as a bug in the library. Please report such
219 problems, along with as much contextual information as possible, to the
220 maintainer of the library.
221 </p>
222
223 <p>
224 It is recommended that users of Boost.MultiIndex always set the
225 invariant-checking mode in debug builds.
226 </p>
227
228 <hr>
229
230 <div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br>
231 Container creation
232 </a></div>
233 <div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
234 Boost.MultiIndex tutorial
235 </a></div>
236 <div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br>
237 Techniques
238 </a></div><br clear="all" style="clear: all;">
239
240 <br>
241
242 <p>Revised July 16th 2014</p>
243
244 <p>&copy; Copyright 2003-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
245 Distributed under the Boost Software
246 License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
247 LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
248 http://www.boost.org/LICENSE_1_0.txt</a>)
249 </p>
250
251 </body>
252 </html>