• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
19Container creation
20</a></div>
21<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
22Boost.MultiIndex tutorial
23</a></div>
24<div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br>
25Techniques
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>
45The concept of <i>Design by Contract</i>, originally developed as part
46of Bertrand Meyer's <a href="http://www.eiffel.com">Eiffel</a> language,
47revolves around the formulation of a <i>contract</i> between the user
48of a library and the implementor, by which the first is required to
49respect some <i>preconditions</i> on the values passed when invoking
50methods of the library, and the implementor guarantees in return
51that certain constraints on the results are met (<i>postconditions</i>),
52as well as the honoring of specified internal consistency rules, called
53<i>invariants</i>. Eiffel natively supports the three parts of the
54contract just described by means of constructs <code>require</code>,
55<code>ensure</code> and <code>invariant</code>, respectively.
56</p>
57
58<p>
59C++ does not enjoy direct support for Design by Contract techniques: these
60are customarily implemented as assertion code, often turned off in
61release mode for performance reasons. Following this approach,
62Boost.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>
69These two modes are independent of each other and can be set on or off
70individually. It is important to note that errors detected by safe mode are
71due in principle to faulty code in the user's program, while
72invariant-checking mode detects potential <i>internal</i> bugs in the
73implementation of Boost.MultiIndex.
74</p>
75
76<h2><a name="safe_mode">Safe mode</a></h2>
77
78<p>
79The idea of adding precondition checking facilities to STL as a debugging aid
80was first introduced by Cay S. Horstmann in his
81<a href="http://www.horstmann.com/safestl.html">Safe STL</a> library and later
82adopted by <a href="http://www.stlport.com/doc/debug_mode.html">STLport Debug
83Mode</a>. Similarly, Boost.MultiIndex features the so-called <i>safe mode</i>
84in which all sorts of preconditions are checked when dealing with iterators
85and functions of the library.
86</p>
87
88<p>
89Boost.MultiIndex safe mode is set by globally defining the macro
90<code>BOOST_MULTI_INDEX_ENABLE_SAFE_MODE</code>. Error conditions
91are checked via the macro <code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, which
92by default resolves to a call to <a href="../../../../libs/assert">
93<code>BOOST_ASSERT</code></a>.
94</p>
95
96<p>
97If 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>
106where <code>expr</code> is the condition checked and <code>error_code</code>
107is 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=special>,</span>               <span class=comment>// containers ought to be different</span>
129  <span class=identifier>unequal_allocators</span>            <span class=comment>// allocators ought to be equal</span>
130<span class=special>};</span>
131
132<span class=special>}</span> <span class=comment>// namespace multi_index::safe_mode</span>
133
134<span class=special>}</span> <span class=comment>// namespace multi_index</span>
135
136<span class=special>}</span> <span class=comment>// namespace boost</span>
137</pre></blockquote>
138
139<p>
140For instance, the following replacement of
141<code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code> throws an exception instead of
142asserting:
143</p>
144
145<blockquote><pre>
146<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>
147
148<span class=keyword>struct</span> <span class=identifier>safe_mode_exception</span>
149<span class=special>{</span>
150  <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>
151    <span class=identifier>error_code</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>)</span>
152  <span class=special>{}</span>
153
154  <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>
155<span class=special>};</span>
156
157<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>
158<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>
159
160<span class=comment>// This has to go before the inclusion of any header from Boost.MultiIndex,
161// except possibly safe_error_codes.hpp.</span>
162</pre></blockquote>
163
164<p>
165Other possibilites, like outputting to a log or firing some kind of alert, are
166also implementable.
167</p>
168
169<p>
170<b>Warning:</b> Safe mode adds a very important overhead to the program
171both in terms of space and time used, so in general it should not be set for
172<code>NDEBUG</code> builds. Also, this mode is intended solely as a debugging aid,
173and programs must not rely on it as part of their normal execution flow: in
174particular, no guarantee is made that all possible precondition errors are diagnosed,
175or that the checks remain stable across different versions of the library.
176</p>
177
178<h3><a name="serialization_and_safe_mode">Serialization and safe mode</a></h3>
179
180<p>
181Iterators restored from an archive are not subject to safe mode checks. This is
182so because it is not possible to automatically know the associated
183<code>multi_index_container</code> of an iterator from the serialization
184information alone. However, if desired, a restored iterator can be converted to a
185checked value by using the following workaround:
186</p>
187
188<blockquote><pre>
189<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
190<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>
191
192<span class=comment>// restore es and it from an archive ar</span>
193<span class=identifier>ar</span><span class=special>&gt;&gt;</span><span class=identifier>es</span><span class=special>;</span>
194<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
195
196// Turn it into a checked value by providing Boost.MultiIndex
197// with info about the associated container.
198// This statement has virtually zero cost if safe mode is turned off.</span>
199<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>
200</pre></blockquote>
201
202<h2><a name="invariant_check">Invariant-checking mode</a></h2>
203
204<p>
205The so called <i>invariant-checking mode</i> of Boost.MultiIndex can be
206set by globally defining the macro
207<code>BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING</code>.
208When this mode is in effect, all public functions of Boost.MultiIndex
209will perform post-execution tests aimed at ensuring that the basic
210internal invariants of the data structures managed are preserved.
211</p>
212
213<p>
214If an invariant test fails, Boost.MultiIndex will indicate the failure
215by means of the unary macro <code>BOOST_MULTI_INDEX_INVARIANT_ASSERT</code>.
216Unless the user provides a definition for this macro, it defaults to
217<a href="../../../../libs/assert">
218<code>BOOST_ASSERT</code></a>. Any assertion of this kind should
219be regarded in principle as a bug in the library. Please report such
220problems, along with as much contextual information as possible, to the
221maintainer of the library.
222</p>
223
224<p>
225It is recommended that users of Boost.MultiIndex always set the
226invariant-checking mode in debug builds.
227</p>
228
229<hr>
230
231<div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br>
232Container creation
233</a></div>
234<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
235Boost.MultiIndex tutorial
236</a></div>
237<div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br>
238Techniques
239</a></div><br clear="all" style="clear: all;">
240
241<br>
242
243<p>Revised May 9th 2020</p>
244
245<p>&copy; Copyright 2003-2020 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
246Distributed under the Boost Software
247License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
248LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
249http://www.boost.org/LICENSE_1_0.txt</a>)
250</p>
251
252</body>
253</html>
254