3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
5 <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7 <link rel="home" href="../index.html" title="Chapter 1. Boost.Contract 1.0.0">
8 <link rel="up" href="../index.html" title="Chapter 1. Boost.Contract 1.0.0">
9 <link rel="prev" href="advanced.html" title="Advanced">
10 <link rel="next" href="examples.html" title="Examples">
12 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13 <table cellpadding="2" width="100%"><tr>
14 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15 <td align="center"><a href="../../../../../index.html">Home</a></td>
16 <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
17 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19 <td align="center"><a href="../../../../../more/index.htm">More</a></td>
22 <div class="spirit-nav">
23 <a accesskey="p" href="advanced.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="examples.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
26 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
27 <a name="boost_contract.extras"></a><a class="link" href="extras.html" title="Extras">Extras</a>
28 </h2></div></div></div>
29 <div class="toc"><dl class="toc">
30 <dt><span class="section"><a href="extras.html#boost_contract.extras.old_value_requirements__templates_">Old
31 Value Requirements (Templates)</a></span></dt>
32 <dt><span class="section"><a href="extras.html#boost_contract.extras.assertion_requirements__templates_">Assertion
33 Requirements (Templates)</a></span></dt>
34 <dt><span class="section"><a href="extras.html#boost_contract.extras.volatile_public_functions">Volatile
35 Public Functions</a></span></dt>
36 <dt><span class="section"><a href="extras.html#boost_contract.extras.move_operations">Move Operations</a></span></dt>
37 <dt><span class="section"><a href="extras.html#boost_contract.extras.unions">Unions</a></span></dt>
38 <dt><span class="section"><a href="extras.html#boost_contract.extras.assertion_levels">Assertion Levels</a></span></dt>
39 <dt><span class="section"><a href="extras.html#boost_contract.extras.disable_contract_checking">Disable
40 Contract Checking</a></span></dt>
41 <dt><span class="section"><a href="extras.html#boost_contract.extras.disable_contract_compilation__macro_interface_">Disable
42 Contract Compilation (Macro Interface)</a></span></dt>
43 <dt><span class="section"><a href="extras.html#boost_contract.extras.separate_body_implementation">Separate
44 Body Implementation</a></span></dt>
45 <dt><span class="section"><a href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_">No
46 Lambda Functions (No C++11)</a></span></dt>
47 <dt><span class="section"><a href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_">No
48 Macros (and No Variadic Macros)</a></span></dt>
51 This section can be consulted selectively for specific topics of interest.
54 <div class="titlepage"><div><div><h3 class="title">
55 <a name="boost_contract.extras.old_value_requirements__templates_"></a><a class="link" href="extras.html#boost_contract.extras.old_value_requirements__templates_" title="Old Value Requirements (Templates)">Old
56 Value Requirements (Templates)</a>
57 </h3></div></div></div>
59 Old values require to copy the expression passed to <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
60 thus the type of that expression needs to be copyable. More precisely, dereferencing
61 an old value pointer of type <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
62 requires <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span></code> to be <code class="computeroutput"><span class="keyword">true</span></code>,
63 otherwise this library will generate a compile-time error.
66 In some cases it might be acceptable, or even desirable, to cause a compile-time
67 error when a program uses old value types that are not copyable (because
68 it is not possible to fully check the correctness of the program as stated
69 by the contract assertions that use these old values). In these cases, programmers
70 can declare old values using <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code>
74 However, in some other cases it might be desirable to simply skip assertions
75 that use old values when the respective old value types are not copyable,
76 without causing compile-time errors. Programmers can do this using <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>
77 instead of <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code>
78 and checking if the old value pointer is not null before dereferencing it
79 in postconditions. For example, consider the following function template
80 that could in general be instantiated for types <code class="computeroutput"><span class="identifier">T</span></code>
81 that are not copy constructible (that is for which <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span></code> is <code class="computeroutput"><span class="keyword">false</span></code>,
82 see <a href="../../../example/features/old_if_copyable.cpp" target="_top"><code class="literal">old_if_copyable.cpp</code></a>):
83 <a href="#ftn.boost_contract.extras.old_value_requirements__templates_.f0" class="footnote" name="boost_contract.extras.old_value_requirements__templates_.f0"><sup class="footnote">[68]</sup></a>
87 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> <span class="comment">// T might or might not be copyable.</span>
88 <span class="keyword">void</span> <span class="identifier">offset</span><span class="special">(</span><span class="identifier">T</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">count</span><span class="special">)</span> <span class="special">{</span>
89 <span class="comment">// No compiler error if T has no copy constructor...</span>
90 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr_if_copyable</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
91 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
92 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
93 <span class="comment">// ...but old value null if T has no copy constructor.</span>
94 <span class="keyword">if</span><span class="special">(</span><span class="identifier">old_x</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span> <span class="special">+</span> <span class="identifier">count</span><span class="special">);</span>
95 <span class="special">})</span>
96 <span class="special">;</span>
98 <span class="identifier">x</span> <span class="special">+=</span> <span class="identifier">count</span><span class="special">;</span>
99 <span class="special">}</span>
104 The old value pointer <code class="computeroutput"><span class="identifier">old_x</span></code>
105 is programmed using <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>.
106 When <code class="computeroutput"><span class="identifier">T</span></code> is copyable, <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
107 behaves like <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>.
108 When <code class="computeroutput"><span class="identifier">T</span></code> is not copyable instead,
109 <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
110 will simply not copy <code class="computeroutput"><span class="identifier">x</span></code> at
111 run-time and leave <code class="computeroutput"><span class="identifier">old_x</span></code>
112 initialized to a null pointer. Therefore, <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>
113 objects like <code class="computeroutput"><span class="identifier">old_x</span></code> must be
114 checked to be not null as in <code class="computeroutput"><span class="keyword">if</span><span class="special">(</span><span class="identifier">old_x</span><span class="special">)</span> <span class="special">...</span></code> before
115 they are dereferenced in postconditions and exception guarantees (to avoid
116 run-time errors of dereferencing null pointers).
119 If the above example used <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code>
120 instead then this library would have generated a compile-time error when
121 <code class="computeroutput"><span class="identifier">offset</span></code> is instantiated with
122 types <code class="computeroutput"><span class="identifier">T</span></code> that are not copy
123 constructible (but only if <code class="computeroutput"><span class="identifier">old_x</span></code>
124 is actually dereferenced somewhere, for example in the contract assertions
125 using <code class="computeroutput"><span class="special">*</span><span class="identifier">old_x</span>
126 <span class="special">...</span></code> or <code class="computeroutput"><span class="identifier">old_x</span><span class="special">->...</span></code>). <a href="#ftn.boost_contract.extras.old_value_requirements__templates_.f1" class="footnote" name="boost_contract.extras.old_value_requirements__templates_.f1"><sup class="footnote">[69]</sup></a>
129 When C++11 <code class="computeroutput"><span class="keyword">auto</span></code> declarations
130 are used with <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>,
131 this library always defaults to using the <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code>
132 type (because its type requirements are more stringent than <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>).
133 For example, the following statements are equivalent:
135 <pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// C++11 auto declarations always use `old_ptr` (never `old_ptr_if_copyable`).</span>
136 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">x</span><span class="special">)></span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
139 If programmers want to relax the copyable type requirement, they must do
140 so explicitly by using the <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>
141 type instead of using <code class="computeroutput"><span class="keyword">auto</span></code> declarations.
144 <a name="boost_contract.extras.old_value_requirements__templates_.h0"></a>
145 <span class="phrase"><a name="boost_contract.extras.old_value_requirements__templates_.old_value_type_traits"></a></span><a class="link" href="extras.html#boost_contract.extras.old_value_requirements__templates_.old_value_type_traits">Old
146 Value Type Traits</a>
149 This library uses <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code>
150 to determine if an old value type is copyable or not, and then <code class="computeroutput"><a class="link" href="../boost/contract/old_value_copy.html" title="Struct template old_value_copy">boost::contract::old_value_copy</a></code>
151 to actually copy the old value.
154 By default, <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
155 is equivalent to <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_copy_constructible</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> and
156 <code class="computeroutput"><a class="link" href="../boost/contract/old_value_copy.html" title="Struct template old_value_copy">boost::contract::old_value_copy</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
157 is implemented using <code class="computeroutput"><span class="identifier">T</span></code>'s
158 copy constructor. However, these type traits can be specialized by programmers
159 for example to avoid making old value copies of types even when they have
160 a copy constructor (maybe because these copy constructors are too expensive),
161 or to make old value copies for types that do not have a copy constructor,
162 or for any other specific need programmers might have for the types in question.
165 For example, the following specialization of <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code>
166 intentionally avoids making old value copies for all expressions of type
167 <code class="computeroutput"><span class="identifier">w</span></code> even if that type has a
168 copy constructor (see <a href="../../../example/features/old_if_copyable.cpp" target="_top"><code class="literal">old_if_copyable.cpp</code></a>):
172 <pre class="programlisting"><span class="comment">// Copyable type but...</span>
173 <span class="keyword">class</span> <span class="identifier">w</span> <span class="special">{</span>
174 <span class="keyword">public</span><span class="special">:</span>
175 <span class="identifier">w</span><span class="special">(</span><span class="identifier">w</span> <span class="keyword">const</span><span class="special">&)</span> <span class="special">{</span> <span class="comment">/* Some very expensive copy operation here... */</span> <span class="special">}</span>
177 <span class="comment">/* ... */</span>
183 <pre class="programlisting"><span class="comment">// ...never copy old values for type `w` (because its copy is too expensive).</span>
184 <span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">contract</span> <span class="special">{</span>
185 <span class="keyword">template</span><span class="special"><></span>
186 <span class="keyword">struct</span> <span class="identifier">is_old_value_copyable</span><span class="special"><</span><span class="identifier">w</span><span class="special">></span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">false_type</span> <span class="special">{};</span>
187 <span class="special">}</span> <span class="special">}</span>
192 On the flip side, the following specializations of <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code>
193 and <code class="computeroutput"><a class="link" href="../boost/contract/old_value_copy.html" title="Struct template old_value_copy">boost::contract::old_value_copy</a></code>
194 make old value copies of expressions of type <code class="computeroutput"><span class="identifier">p</span></code>
195 even if that type does not actually have a copy constructor (see <a href="../../../example/features/old_if_copyable.cpp" target="_top"><code class="literal">old_if_copyable.cpp</code></a>):
199 <pre class="programlisting"><span class="comment">// Non-copyable type but...</span>
200 <span class="keyword">class</span> <span class="identifier">p</span> <span class="special">:</span> <span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span> <span class="special">{</span>
201 <span class="keyword">int</span><span class="special">*</span> <span class="identifier">num_</span><span class="special">;</span>
203 <span class="keyword">friend</span> <span class="keyword">struct</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_value_copy</span><span class="special"><</span><span class="identifier">p</span><span class="special">>;</span>
205 <span class="comment">/* ... */</span>
211 <pre class="programlisting"><span class="comment">// ...still copy old values for type `p` (using a deep copy).</span>
212 <span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">contract</span> <span class="special">{</span>
213 <span class="keyword">template</span><span class="special"><></span>
214 <span class="keyword">struct</span> <span class="identifier">old_value_copy</span><span class="special"><</span><span class="identifier">p</span><span class="special">></span> <span class="special">{</span>
215 <span class="keyword">explicit</span> <span class="identifier">old_value_copy</span><span class="special">(</span><span class="identifier">p</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">old</span><span class="special">)</span> <span class="special">{</span>
216 <span class="special">*</span><span class="identifier">old_</span><span class="special">.</span><span class="identifier">num_</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">old</span><span class="special">.</span><span class="identifier">num_</span><span class="special">;</span> <span class="comment">// Deep copy pointed value.</span>
217 <span class="special">}</span>
219 <span class="identifier">p</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">old</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">old_</span><span class="special">;</span> <span class="special">}</span>
221 <span class="keyword">private</span><span class="special">:</span>
222 <span class="identifier">p</span> <span class="identifier">old_</span><span class="special">;</span>
223 <span class="special">};</span>
225 <span class="keyword">template</span><span class="special"><></span>
226 <span class="keyword">struct</span> <span class="identifier">is_old_value_copyable</span><span class="special"><</span><span class="identifier">p</span><span class="special">></span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">true_type</span> <span class="special">{};</span>
227 <span class="special">}</span> <span class="special">}</span>
232 In general, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_copy_constructible</span></code> and therefore <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code>
233 require C++11 <code class="computeroutput"><span class="keyword">decltype</span></code> and SFINAE
234 to automatically detect if a given type is copyable or not. On non-C++11
235 compilers, it is possible to inherit the old value type from <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span></code>, or use <code class="computeroutput"><span class="identifier">BOOST_MOVABLE_BUT_NOT_COPYABLE</span></code>,
236 or specialize <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_copy_constructible</span></code> (see <a href="http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/boost_typetraits/reference/is_copy_constructible.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_copy_constructible</span></code></a> documentation
237 for more information), or just specialize <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code>.
238 For example, for a non-copyable type <code class="computeroutput"><span class="identifier">n</span></code>
239 the following code will work also on non-C++11 compilers (see <a href="../../../example/features/old_if_copyable.cpp" target="_top"><code class="literal">old_if_copyable.cpp</code></a>):
243 <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">n</span> <span class="special">{</span> <span class="comment">// Do not want to use boost::noncopyable but...</span>
244 <span class="keyword">int</span> <span class="identifier">num_</span><span class="special">;</span>
246 <span class="keyword">private</span><span class="special">:</span>
247 <span class="identifier">n</span><span class="special">(</span><span class="identifier">n</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">// ...unimplemented private copy constructor (so non-copyable).</span>
249 <span class="comment">/* ... */</span>
255 <pre class="programlisting"><span class="comment">// Specialize `boost::is_copy_constructible` (no need for this on C++11).</span>
256 <span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">contract</span> <span class="special">{</span>
257 <span class="keyword">template</span><span class="special"><></span>
258 <span class="keyword">struct</span> <span class="identifier">is_old_value_copyable</span><span class="special"><</span><span class="identifier">n</span><span class="special">></span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">false_type</span> <span class="special">{};</span>
259 <span class="special">}</span> <span class="special">}</span>
264 <div class="section">
265 <div class="titlepage"><div><div><h3 class="title">
266 <a name="boost_contract.extras.assertion_requirements__templates_"></a><a class="link" href="extras.html#boost_contract.extras.assertion_requirements__templates_" title="Assertion Requirements (Templates)">Assertion
267 Requirements (Templates)</a>
268 </h3></div></div></div>
270 In general, assertions can introduce a new set of requirements on the types
271 used by the program. Some of these type requirements might be necessary only
272 to check the assertions and they would not be required by the program otherwise.
275 In some cases it might be acceptable, or even desirable, to cause a compile-time
276 error when a program uses types that do not provide all the operations needed
277 to check contract assertions (because it is not possible to fully check the
278 correctness of the program as specified by its contracts). In these cases,
279 programmers can specify contract assertions as we have seen so far, compilation
280 will fail if user types do not provide all operations necessary to check
284 However, in some other cases it might be desirable to not augment the type
285 requirements of a program just because of contract assertions and to simply
286 skip assertions when user types do not provide all the operations necessary
287 to check them, without causing compile-time errors. Programmers can do this
288 using <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
289 on C++17 compilers, and <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
290 (or <code class="computeroutput"><a class="link" href="../boost/contract/condition_if_c.html" title="Function template condition_if_c">boost::contract::condition_if_c</a></code>)
291 on non-C++17 compilers.
294 For example, let's consider the following <code class="computeroutput"><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
295 class template equivalent to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>.
296 C++ <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> does
297 not require that its value type parameter <code class="computeroutput"><span class="identifier">T</span></code>
298 has an equality operator <code class="computeroutput"><span class="special">==</span></code>
299 (it only requires <code class="computeroutput"><span class="identifier">T</span></code> to be
300 copy constructible, see <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
301 documentation). However, the contracts for the <code class="computeroutput"><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">value</span><span class="special">)</span></code>
302 public function include a postcondition <code class="computeroutput"><span class="identifier">back</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">value</span></code>
303 that introduces the new requirement that <code class="computeroutput"><span class="identifier">T</span></code>
304 must also have an equality operator <code class="computeroutput"><span class="special">==</span></code>.
305 Programmers can specify this postcondition as usual with <code class="computeroutput"><span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">back</span><span class="special">()</span>
306 <span class="special">==</span> <span class="identifier">value</span><span class="special">)</span></code> an let the program fail to compile when
307 users instantiate <code class="computeroutput"><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
308 with a type <code class="computeroutput"><span class="identifier">T</span></code> that does not
309 provide an equality operator <code class="computeroutput"><span class="special">==</span></code>.
310 Otherwise, programmers can guard this postcondition using C++17 <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
311 to evaluate the asserted condition only for types <code class="computeroutput"><span class="identifier">T</span></code>
312 that have an equality operator <code class="computeroutput"><span class="special">==</span></code>
313 and skip it otherwise. <a href="#ftn.boost_contract.extras.assertion_requirements__templates_.f0" class="footnote" name="boost_contract.extras.assertion_requirements__templates_.f0"><sup class="footnote">[70]</sup></a> For example:
315 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
316 <span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
317 <span class="keyword">public</span><span class="special">:</span>
318 <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
319 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boot</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
320 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
321 <span class="comment">// Guard with `if constexpr` for T without `==`.</span>
322 <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">)</span>
323 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">back</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">value</span><span class="special">);</span>
324 <span class="special">})</span>
325 <span class="special">;</span>
327 <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">value</span><span class="special">);</span>
328 <span class="special">}</span>
330 <span class="comment">/* ... */</span>
333 More in general, <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
334 can be used to guard a mix of both old value copies and contract assertions
335 that introduce specific extra type requirements. For example, the following
336 <code class="computeroutput"><span class="identifier">swap</span></code> function can be called
337 on any type <code class="computeroutput"><span class="identifier">T</span></code> that is movable
338 but its old value copies and postcondition assertions are evaluated only
339 for types <code class="computeroutput"><span class="identifier">T</span></code> that are also
340 copyable and have an equality operator <code class="computeroutput"><span class="special">==</span></code>
341 (see <a href="../../../example/features/if_constexpr.cpp" target="_top"><code class="literal">if_constexpr.cpp</code></a>):
345 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
346 <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
347 <span class="keyword">constexpr</span> <span class="keyword">bool</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">is_old_value_copyable</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">&&</span>
348 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span>
349 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">old_x</span><span class="special">,</span> <span class="identifier">old_y</span><span class="special">;</span>
350 <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Contract requires copyable T...</span>
351 <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
352 <span class="identifier">old_y</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span>
353 <span class="special">}</span>
354 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
355 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
356 <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// ... and T with `==`...</span>
357 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_y</span><span class="special">);</span>
358 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
359 <span class="special">}</span>
360 <span class="special">})</span>
361 <span class="special">;</span>
363 <span class="identifier">T</span> <span class="identifier">t</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// ...but body only requires movable T.</span>
364 <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span>
365 <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">t</span><span class="special">);</span>
366 <span class="special">}</span>
371 <a name="boost_contract.extras.assertion_requirements__templates_.h0"></a>
372 <span class="phrase"><a name="boost_contract.extras.assertion_requirements__templates_.no__code__phrase_role__keyword__if__phrase___phrase_role__keyword__constexpr__phrase___code___no_c__17_"></a></span><a class="link" href="extras.html#boost_contract.extras.assertion_requirements__templates_.no__code__phrase_role__keyword__if__phrase___phrase_role__keyword__constexpr__phrase___code___no_c__17_">No
373 <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
377 On non-C++17 compilers where <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code> is not available, it is possible
378 to use <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
379 to skip assertions based on type requirements (even if this code is less
380 readable and more verbose than using <code class="computeroutput"><span class="keyword">if</span>
381 <span class="keyword">constexpr</span></code>). For example (see <a href="../../../example/features/condition_if.cpp" target="_top"><code class="literal">condition_if.cpp</code></a>):
385 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
386 <span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
387 <span class="keyword">public</span><span class="special">:</span>
388 <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
389 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
390 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
391 <span class="comment">// Instead of `ASSERT(back() == value)` for T without `==`.</span>
392 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span>
393 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">condition_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">>(</span>
394 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal_to</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(),</span>
395 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">back</span><span class="special">()),</span>
396 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">value</span><span class="special">)</span>
397 <span class="special">)</span>
398 <span class="special">)</span>
399 <span class="special">);</span>
400 <span class="special">})</span>
401 <span class="special">;</span>
403 <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">value</span><span class="special">);</span>
404 <span class="special">}</span>
406 <span class="comment">/* ... */</span>
411 More in general, <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
414 <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">condition_if</span><span class="special"><</span><span class="identifier">Pred</span><span class="special">>(</span>
415 <span class="identifier">cond</span>
416 <span class="special">)</span>
419 Where <code class="computeroutput"><span class="identifier">Pred</span></code> is a nullary boolean
420 meta-function and <code class="computeroutput"><span class="identifier">cond</span></code> is
421 a nullary boolean functor. If <code class="computeroutput"><span class="identifier">Pred</span><span class="special">::</span><span class="identifier">value</span></code>
422 is statically evaluated to be <code class="computeroutput"><span class="keyword">true</span></code>
423 at compile-time then <code class="computeroutput"><span class="identifier">cond</span><span class="special">()</span></code> is called at run-time and its boolean result
424 is returned by the enclosing <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
425 call. Otherwise, if <code class="computeroutput"><span class="identifier">Pred</span><span class="special">::</span><span class="identifier">value</span></code>
426 is statically evaluated to be <code class="computeroutput"><span class="keyword">false</span></code>
427 at compile-time then <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
428 trivially returns <code class="computeroutput"><span class="keyword">true</span></code>. Therefore,
429 if <code class="computeroutput"><span class="identifier">cond</span></code> is a functor template
430 instantiation (not just a functor) then its call that contains the assertion
431 operations with the extra type requirements (e.g., the equality operator
432 <code class="computeroutput"><span class="special">==</span></code>) will not be actually instantiated
433 and compiled unless the compiler determines at compile-time that <code class="computeroutput"><span class="identifier">Pred</span><span class="special">::</span><span class="identifier">value</span></code> is <code class="computeroutput"><span class="keyword">true</span></code>
434 (when used this way, functor templates like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal_to</span></code>
435 and C++14 generic lambdas can be used to program <code class="computeroutput"><span class="identifier">cond</span></code>,
436 but C++11 lambdas cannot).
439 The <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
440 function template is a special case of the more general <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>,
441 specifically <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">Pred</span><span class="special">>(</span><span class="identifier">cond</span><span class="special">)</span></code> is logically equivalent to <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code><code class="computeroutput"><span class="special"><</span><span class="identifier">Pred</span><span class="special">>(</span><span class="identifier">cond</span><span class="special">).</span><span class="identifier">else_</span><span class="special">([]</span> <span class="special">{</span> <span class="keyword">return</span>
442 <span class="keyword">true</span><span class="special">;</span> <span class="special">})</span></code>. <a href="#ftn.boost_contract.extras.assertion_requirements__templates_.f1" class="footnote" name="boost_contract.extras.assertion_requirements__templates_.f1"><sup class="footnote">[71]</sup></a> The <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>
443 function template also accepts a number of optional <span class="emphasis"><em>else-if</em></span>
444 statements and one optional <span class="emphasis"><em>else</em></span> statement:
446 <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">call_if</span><span class="special"><</span><span class="identifier">Pred1</span><span class="special">>(</span>
447 <span class="identifier">t1</span>
448 <span class="special">).</span><span class="keyword">template</span> <span class="identifier">else_if</span><span class="special"><</span><span class="identifier">Pred2</span><span class="special">>(</span> <span class="comment">// Optional.</span>
449 <span class="identifier">t2</span>
450 <span class="special">)</span>
451 <span class="special">...</span> <span class="comment">// Optionally, other `else_if` statements.</span>
452 <span class="special">.</span><span class="identifier">else_</span><span class="special">(</span> <span class="comment">// Optional for `void` functors, otherwise required.</span>
453 <span class="identifier">e</span>
454 <span class="special">)</span>
457 Where <code class="computeroutput"><span class="identifier">Pred1</span></code>, <code class="computeroutput"><span class="identifier">Pred2</span></code>, ... are nullary boolean meta-functions
458 and <code class="computeroutput"><span class="identifier">t1</span></code>, <code class="computeroutput"><span class="identifier">t2</span></code>,
459 ..., <code class="computeroutput"><span class="identifier">e</span></code> are nullary functors.
460 The return types of the functor calls <code class="computeroutput"><span class="identifier">t1</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">t2</span><span class="special">()</span></code>, ..., <code class="computeroutput"><span class="identifier">e</span><span class="special">()</span></code> must either be all the same (including
461 possibly all <code class="computeroutput"><span class="keyword">void</span></code>) or be of
462 types implicitly convertible into one another. At run-time <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code> will
463 call the functor <code class="computeroutput"><span class="identifier">t1</span><span class="special">()</span></code>,
464 or <code class="computeroutput"><span class="identifier">t2</span><span class="special">()</span></code>,
465 ..., or <code class="computeroutput"><span class="identifier">e</span><span class="special">()</span></code>
466 depending on which meta-function <code class="computeroutput"><span class="identifier">Pred1</span><span class="special">::</span><span class="identifier">value</span></code>,
467 <code class="computeroutput"><span class="identifier">Pred2</span><span class="special">::</span><span class="identifier">value</span></code>, ... is statically evaluated to be
468 <code class="computeroutput"><span class="keyword">true</span></code> or <code class="computeroutput"><span class="keyword">false</span></code>
469 at compile-time, and it will return the value returned by the functor being
470 called. If <code class="computeroutput"><span class="identifier">t1</span></code>, <code class="computeroutput"><span class="identifier">t2</span></code>, ..., <code class="computeroutput"><span class="identifier">e</span></code>
471 are functor template instantiations (not just functors) then their code will
472 only be compiled if the compiler determines they need to be actually called
473 at run-time (so only if the related <code class="computeroutput"><span class="identifier">Pred1</span><span class="special">::</span><span class="identifier">value</span></code>,
474 <code class="computeroutput"><span class="identifier">Pred2</span><span class="special">::</span><span class="identifier">value</span></code>, ... are respectively evaluated to
475 be <code class="computeroutput"><span class="keyword">true</span></code> or <code class="computeroutput"><span class="keyword">false</span></code>
476 at compile-time). All the <code class="computeroutput"><span class="identifier">else_if</span><span class="special"><...>(...)</span></code> statements are optional.
477 The <code class="computeroutput"><span class="identifier">else_</span><span class="special">(...)</span></code>
478 statement is optional if the functor calls return <code class="computeroutput"><span class="keyword">void</span></code>,
479 otherwise it is required.
482 In general, <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>
483 can be used to program contract assertions that compile and check different
484 functor templates depending on related predicates being statically evaluated
485 to be <code class="computeroutput"><span class="keyword">true</span></code> or <code class="computeroutput"><span class="keyword">false</span></code> at compile-time (but in most cases
486 <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
487 should be sufficient and less verbose to use). The <code class="computeroutput"><a class="link" href="../boost/contract/condition_if_c.html" title="Function template condition_if_c">boost::contract::condition_if_c</a></code>,
488 <code class="computeroutput"><a class="link" href="../boost/contract/call_if_c.html" title="Function template call_if_c">boost::contract::call_if_c</a></code>,
489 and <code class="computeroutput"><span class="special">.</span><span class="identifier">else_if_c</span></code>
490 function templates work similarly to their counterparts without the <code class="computeroutput"><span class="special">...</span><span class="identifier">_c</span></code> postfix
491 seen so far, but they take their predicate template parameters as static
492 boolean values instead of nullary boolean meta-functions.
495 On compilers that support C++17 <code class="computeroutput"><span class="keyword">if</span>
496 <span class="keyword">constexpr</span></code> there should be no need
497 to use <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
498 or <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>
499 because <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
500 can be used instead (making the code more readable and easier to program).
501 <a href="#ftn.boost_contract.extras.assertion_requirements__templates_.f2" class="footnote" name="boost_contract.extras.assertion_requirements__templates_.f2"><sup class="footnote">[72]</sup></a>
504 <div class="section">
505 <div class="titlepage"><div><div><h3 class="title">
506 <a name="boost_contract.extras.volatile_public_functions"></a><a class="link" href="extras.html#boost_contract.extras.volatile_public_functions" title="Volatile Public Functions">Volatile
508 </h3></div></div></div>
510 This library allows to specify a different set of class invariants to check
511 for volatile public functions. These <span class="emphasis"><em>volatile class invariants</em></span>
512 are programmed in a public <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code> function, named <code class="computeroutput"><span class="identifier">invariant</span></code>,
513 taking no argument, and returning <code class="computeroutput"><span class="keyword">void</span></code>
514 (see <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999724496.html" title="Macro BOOST_CONTRACT_INVARIANT_FUNC">BOOST_CONTRACT_INVARIANT_FUNC</a></code>
515 to name the invariant function differently from <code class="computeroutput"><span class="identifier">invariant</span></code>
516 and <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access Specifiers</a>
517 to not have to declare it <code class="computeroutput"><span class="keyword">public</span></code>).
518 Classes that do no have invariants for their volatile public functions, simply
519 do not declare the <code class="computeroutput"><span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">volatile</span></code> function.
522 In general, <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
523 invariants work the same as <code class="computeroutput"><span class="keyword">const</span></code>
524 invariants (see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class
525 Invariants</a>) with the only difference that <code class="computeroutput"><span class="keyword">volatile</span></code>
526 and <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
527 functions check <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
528 invariants while non-<code class="computeroutput"><span class="keyword">const</span></code> (i.e.,
529 neither <code class="computeroutput"><span class="keyword">const</span></code> nor <code class="computeroutput"><span class="keyword">volatile</span></code>) and <code class="computeroutput"><span class="keyword">const</span></code>
530 functions check <code class="computeroutput"><span class="keyword">const</span></code> invariants.
531 A given class can specify any combination of <code class="computeroutput"><span class="keyword">static</span></code>,
532 <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>,
533 and <code class="computeroutput"><span class="keyword">const</span></code> invariant functions
534 (see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class Invariants</a>):
535 <a href="#ftn.boost_contract.extras.volatile_public_functions.f0" class="footnote" name="boost_contract.extras.volatile_public_functions.f0"><sup class="footnote">[73]</sup></a>
537 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
538 <li class="listitem">
539 Constructors check <code class="computeroutput"><span class="keyword">static</span></code>
540 invariants at entry and exit (even if an exception is thrown), plus
541 <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
542 and <code class="computeroutput"><span class="keyword">const</span></code> invariants in
543 that order at exit but only if no exception is thrown.
545 <li class="listitem">
546 Destructors check <code class="computeroutput"><span class="keyword">static</span></code>
547 invariants at entry and exit (even if an exception is thrown), plus
548 <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
549 and <code class="computeroutput"><span class="keyword">const</span></code> invariants in
550 that order at entry (and at exit but only if an exception is thrown,
551 even is destructors should in general never throw in C++).
553 <li class="listitem">
554 Both non-<code class="computeroutput"><span class="keyword">const</span></code> and <code class="computeroutput"><span class="keyword">const</span></code> public functions check <code class="computeroutput"><span class="keyword">static</span></code> and <code class="computeroutput"><span class="keyword">const</span></code>
555 invariants at entry and at exit (even if an exception is thrown).
557 <li class="listitem">
558 Both <code class="computeroutput"><span class="keyword">volatile</span></code> and <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
559 public functions check <code class="computeroutput"><span class="keyword">static</span></code>
560 and <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
561 invariants at entry and at exit (even if an exception is thrown).
565 These rules ensure that volatile class invariants are correctly checked (see
566 <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constructor_calls" title="Constructor Calls">Constructor
567 Calls</a>, <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.destructor_calls" title="Destructor Calls">Destructor
568 Calls</a>, and <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.public_function_calls" title="Public Function Calls">Public
569 Function Calls</a>). For example (see <a href="../../../example/features/volatile.cpp" target="_top"><code class="literal">volatile.cpp</code></a>):
573 <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
574 <span class="keyword">public</span><span class="special">:</span>
575 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">static_invariant</span><span class="special">();</span> <span class="comment">// Static invariants.</span>
576 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">;</span> <span class="comment">// Volatile invariants.</span>
577 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> <span class="comment">// Const invariants.</span>
579 <span class="identifier">u</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Check static, volatile, and const invariants.</span>
580 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span><span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
581 <span class="special">}</span>
583 <span class="special">~</span><span class="identifier">u</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Check static, volatile, and const invariants.</span>
584 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">destructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
585 <span class="special">}</span>
587 <span class="keyword">void</span> <span class="identifier">nc</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Check static and const invariants.</span>
588 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
589 <span class="special">}</span>
591 <span class="keyword">void</span> <span class="identifier">c</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="comment">// Check static and const invariants.</span>
592 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
593 <span class="special">}</span>
595 <span class="keyword">void</span> <span class="identifier">v</span><span class="special">()</span> <span class="keyword">volatile</span> <span class="special">{</span> <span class="comment">// Check static and volatile invariants.</span>
596 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
597 <span class="special">}</span>
599 <span class="keyword">void</span> <span class="identifier">cv</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">volatile</span> <span class="special">{</span> <span class="comment">// Check static and volatile invariants.</span>
600 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
601 <span class="special">}</span>
603 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">s</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Check static invariants only.</span>
604 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span><span class="identifier">u</span><span class="special">>();</span>
605 <span class="special">}</span>
606 <span class="special">};</span>
611 This library does not automatically check <code class="computeroutput"><span class="keyword">const</span>
612 <span class="keyword">volatile</span></code> invariants for non-<code class="computeroutput"><span class="keyword">volatile</span></code> functions. However, if the contract
613 specifications require it, programmers can explicitly call the <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
614 invariant function from the <code class="computeroutput"><span class="keyword">const</span></code>
615 invariant function (preferably in that order to be consistent with the order
616 <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
617 and <code class="computeroutput"><span class="keyword">const</span></code> invariants are checked
618 for constructors and destructors). That way all public functions, <code class="computeroutput"><span class="keyword">volatile</span></code> or not, will check <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
619 invariants (while only <code class="computeroutput"><span class="keyword">const</span></code>
620 and non-<code class="computeroutput"><span class="keyword">const</span></code> public functions
621 will check only <code class="computeroutput"><span class="keyword">const</span></code> invariants,
622 correctly so because the <code class="computeroutput"><span class="keyword">volatile</span></code>
623 qualifier shall not be stripped away): <a href="#ftn.boost_contract.extras.volatile_public_functions.f1" class="footnote" name="boost_contract.extras.volatile_public_functions.f1"><sup class="footnote">[74]</sup></a>
625 <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
626 <span class="keyword">public</span><span class="special">:</span>
627 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">volatile</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span> <span class="comment">// Volatile invariants.</span>
629 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
630 <span class="keyword">auto</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">*</span> <span class="identifier">cv</span> <span class="special">=</span> <span class="keyword">this</span><span class="special">;</span> <span class="identifier">cv</span><span class="special">-></span><span class="identifier">invariant</span><span class="special">();</span> <span class="comment">// Call `const volatile` invariant function above.</span>
631 <span class="special">...</span> <span class="comment">// Other non-volatile invariants.</span>
632 <span class="special">}</span>
634 <span class="special">...</span>
635 <span class="special">};</span>
638 (As usual, private and protected functions do not check any invariant, not
639 even when they are <code class="computeroutput"><span class="keyword">volatile</span></code>
640 or <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>,
641 see <a class="link" href="advanced.html#boost_contract.advanced.private_and_protected_functions" title="Private and Protected Functions">Private
642 and Protected Functions</a>).
645 <div class="section">
646 <div class="titlepage"><div><div><h3 class="title">
647 <a name="boost_contract.extras.move_operations"></a><a class="link" href="extras.html#boost_contract.extras.move_operations" title="Move Operations">Move Operations</a>
648 </h3></div></div></div>
650 As with all public operations of a class, also public move operations should
651 maintain class invariants (see <a class="link" href="bibliography.html#Stroustrup13_anchor">[Stroustrup13]</a>,
652 p. 520). Specifically, at a minimum C++ requires the following:
654 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
655 <li class="listitem">
656 The moved-from object can be copy assigned.
658 <li class="listitem">
659 The moved-from object can be move assigned.
661 <li class="listitem">
662 The moved-from object can be destroyed (if not for any other reason,
663 this requires that class invariants are maintained by move operations
664 because the destructor of the moved-from object requires class invariants
665 to be satisfied at its entry, as always with destructors see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.destructor_calls" title="Destructor Calls">Destructor
670 Therefore, both the move constructor and the move assignment operator need
671 to maintain the class invariants of the moved-from object so their contracts
672 can be programmed using <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
673 and <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45394998885120.html" title="Function template public_function">boost::contract::public_function</a></code>
674 as usual. For example (see <a href="../../../example/features/move.cpp" target="_top"><code class="literal">move.cpp</code></a>):
678 <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">circular_buffer</span> <span class="special">:</span>
679 <span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">circular_buffer</span><span class="special">></span> <span class="special">{</span>
680 <span class="keyword">public</span><span class="special">:</span>
681 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
682 <span class="keyword">if</span><span class="special">(!</span><span class="identifier">moved</span><span class="special">())</span> <span class="special">{</span> <span class="comment">// Do not check (some) invariants for moved-from objects.</span>
683 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">index</span><span class="special">()</span> <span class="special"><</span> <span class="identifier">size</span><span class="special">());</span>
684 <span class="special">}</span>
685 <span class="comment">// More invariants here that hold also for moved-from objects (e.g.,</span>
686 <span class="comment">// all assertions necessary to successfully destroy moved-from objects).</span>
687 <span class="special">}</span>
689 <span class="comment">// Move constructor.</span>
690 <span class="identifier">circular_buffer</span><span class="special">(</span><span class="identifier">circular_buffer</span><span class="special">&&</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">:</span>
691 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">circular_buffer</span><span class="special">>([&]</span> <span class="special">{</span>
692 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(!</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">moved</span><span class="special">());</span>
693 <span class="special">})</span>
694 <span class="special">{</span>
695 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
696 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
697 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(!</span><span class="identifier">moved</span><span class="special">());</span>
698 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">moved</span><span class="special">());</span>
699 <span class="special">})</span>
700 <span class="special">;</span>
702 <span class="identifier">move</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special"><</span><span class="identifier">circular_buffer</span><span class="special">>(</span><span class="identifier">other</span><span class="special">));</span>
703 <span class="special">}</span>
705 <span class="comment">// Move assignment.</span>
706 <span class="identifier">circular_buffer</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">circular_buffer</span><span class="special">&&</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">{</span>
707 <span class="comment">// Moved-from can be (move) assigned (so no pre `!moved()` here).</span>
708 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
709 <span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span>
710 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(!</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">moved</span><span class="special">());</span>
711 <span class="special">})</span>
712 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
713 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(!</span><span class="identifier">moved</span><span class="special">());</span>
714 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">moved</span><span class="special">());</span>
715 <span class="special">})</span>
716 <span class="special">;</span>
718 <span class="keyword">return</span> <span class="identifier">move</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special"><</span><span class="identifier">circular_buffer</span><span class="special">>(</span><span class="identifier">other</span><span class="special">));</span>
719 <span class="special">}</span>
721 <span class="special">~</span><span class="identifier">circular_buffer</span><span class="special">()</span> <span class="special">{</span>
722 <span class="comment">// Moved-from can always be destroyed (in fact no preconditions).</span>
723 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">destructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
724 <span class="special">}</span>
726 <span class="keyword">bool</span> <span class="identifier">moved</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
727 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
728 <span class="keyword">return</span> <span class="identifier">moved_</span><span class="special">;</span>
729 <span class="special">}</span>
731 <span class="keyword">private</span><span class="special">:</span>
732 <span class="keyword">bool</span> <span class="identifier">moved_</span><span class="special">;</span>
734 <span class="comment">/* ... */</span>
739 This example assumes that it is possible to call the public function <code class="computeroutput"><span class="identifier">moved</span><span class="special">()</span></code>
740 on the moved-from object. <a href="#ftn.boost_contract.extras.move_operations.f0" class="footnote" name="boost_contract.extras.move_operations.f0"><sup class="footnote">[75]</sup></a>
742 <div class="note"><table border="0" summary="Note">
744 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
745 <th align="left">Note</th>
747 <tr><td align="left" valign="top"><p>
748 The default move constructor and move assignment operator generated by
749 C++ will not automatically check contracts. Therefore, unless the move
750 operations are not public or they have no preconditions, no postconditions,
751 and their class has no invariants, programmers should manually define them
752 using <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>,
753 <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>,
754 and <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45394998885120.html" title="Function template public_function">boost::contract::public_function</a></code>
755 instead of relying on their default implementations generated by C++. (Same
756 as for all other operations automatically implemented by C++.)
760 As always, programmers can decide to not program contracts for a given type.
761 Specifically, they might decide to not program contracts for a class that
762 needs to be moved in order to avoid the run-time overhead of checking contract
763 assertions and to maximize performance (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.benefits_and_costs" title="Benefits and Costs">Benefits
767 <div class="section">
768 <div class="titlepage"><div><div><h3 class="title">
769 <a name="boost_contract.extras.unions"></a><a class="link" href="extras.html#boost_contract.extras.unions" title="Unions">Unions</a>
770 </h3></div></div></div>
772 A C++ <code class="computeroutput"><span class="keyword">union</span></code> cannot have virtual
773 functions, base classes, and cannot be used as a base class thus subcontracting
774 (<code class="computeroutput"><a class="link" href="../boost/contract/virtual_.html" title="Class virtual_">boost::contract::virtual_</a></code>,
775 <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>,
776 etc.) do not apply to unions. Also a <code class="computeroutput"><span class="keyword">union</span></code>
777 cannot inherit from <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
778 (because it cannot have base classes), instead <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
779 is used to declare a local object that checks constructor preconditions (at
780 the very beginning of the constructor before old value copies and other contracts,
781 see declaration of <code class="computeroutput"><span class="identifier">pre</span></code> in
782 the example below). A part from that, this library is used as usual to program
783 contracts for unions. For example (see <a href="../../../example/features/union.cpp" target="_top"><code class="literal">union.cpp</code></a>):
787 <pre class="programlisting"><span class="keyword">union</span> <span class="identifier">positive</span> <span class="special">{</span>
788 <span class="keyword">public</span><span class="special">:</span>
789 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">static_invariant</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Static class invariants (as usual).</span>
790 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
791 <span class="special">}</span>
793 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="comment">// Class invariants (as usual).</span>
794 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">i_</span> <span class="special">></span> <span class="number">0</span><span class="special">);</span>
795 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">d_</span> <span class="special">></span> <span class="number">0</span><span class="special">);</span>
796 <span class="special">}</span>
798 <span class="comment">// Contracts for constructor, as usual but...</span>
799 <span class="keyword">explicit</span> <span class="identifier">positive</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">d_</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{</span>
800 <span class="comment">// ...unions cannot have bases so constructor preconditions here.</span>
801 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">positive</span><span class="special">></span> <span class="identifier">pre</span><span class="special">([&]</span> <span class="special">{</span>
802 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">></span> <span class="number">0</span><span class="special">);</span>
803 <span class="special">});</span>
804 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_instances</span> <span class="special">=</span>
805 <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">instances</span><span class="special">());</span>
806 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
807 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
808 <span class="special">{</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">;</span> <span class="identifier">get</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
809 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_instances</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
810 <span class="special">})</span>
811 <span class="special">;</span>
813 <span class="identifier">i_</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span>
814 <span class="special">++</span><span class="identifier">instances_</span><span class="special">;</span>
815 <span class="special">}</span>
817 <span class="comment">// Contracts for destructor (as usual).</span>
818 <span class="special">~</span><span class="identifier">positive</span><span class="special">()</span> <span class="special">{</span>
819 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_instances</span> <span class="special">=</span>
820 <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">instances</span><span class="special">());</span>
821 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">destructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
822 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
823 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_instances</span> <span class="special">-</span> <span class="number">1</span><span class="special">);</span>
824 <span class="special">})</span>
825 <span class="special">;</span>
827 <span class="special">--</span><span class="identifier">instances_</span><span class="special">;</span>
828 <span class="special">}</span>
830 <span class="comment">// Contracts for public function (as usual, but no virtual or override).</span>
831 <span class="keyword">void</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
832 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
833 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
834 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">></span> <span class="number">0</span><span class="special">);</span>
835 <span class="special">})</span>
836 <span class="special">;</span>
838 <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">i_</span><span class="special">;</span>
839 <span class="special">}</span>
841 <span class="comment">// Contracts for static public function (as usual).</span>
842 <span class="keyword">static</span> <span class="keyword">int</span> <span class="identifier">instances</span><span class="special">()</span> <span class="special">{</span>
843 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span><span class="identifier">positive</span><span class="special">>();</span>
844 <span class="keyword">return</span> <span class="identifier">instances_</span><span class="special">;</span>
845 <span class="special">}</span>
847 <span class="keyword">private</span><span class="special">:</span>
848 <span class="keyword">int</span> <span class="identifier">i_</span><span class="special">;</span>
849 <span class="keyword">double</span> <span class="identifier">d_</span><span class="special">;</span>
851 <span class="comment">/* ... */</span>
856 <div class="section">
857 <div class="titlepage"><div><div><h3 class="title">
858 <a name="boost_contract.extras.assertion_levels"></a><a class="link" href="extras.html#boost_contract.extras.assertion_levels" title="Assertion Levels">Assertion Levels</a>
859 </h3></div></div></div>
861 This library provides three predefined <span class="emphasis"><em>assertion levels</em></span>
862 that can be used to selectively disable assertions depending on their computational
863 complexity: <a href="#ftn.boost_contract.extras.assertion_levels.f0" class="footnote" name="boost_contract.extras.assertion_levels.f0"><sup class="footnote">[76]</sup></a>
865 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
866 <li class="listitem">
867 <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
868 is used to assert conditions that are not computationally expensive,
869 at least compared to the cost of executing the function body. These assertions
870 are the ones we have seen so far, they are always checked at run-time
871 and they cannot be disabled.
873 <li class="listitem">
874 <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45395000817520.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
875 is used to assert conditions that are computationally expensive compared
876 to the cost of executing the function body. These assertions are not
877 checked at run-time unless programmers explicitly define <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_AUDITS.html" title="Macro BOOST_CONTRACT_AUDITS">BOOST_CONTRACT_AUDITS</a></code>
878 (undefined by default), but the asserted conditions are always compiled
879 and therefore validated syntactically (even when they are not actually
880 evaluated and checked at run-time).
882 <li class="listitem">
883 <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45395027441616.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
884 is used to assert conditions that are computationally prohibitive, at
885 least compared to the cost of executing the function body. These assertions
886 are never evaluated or checked at run-time, but the asserted conditions
887 are always compiled and therefore validated syntactically (so these assertions
888 can serve as formal comments to the code).
892 In addition, <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_CHECK_AUDIT.html" title="Macro BOOST_CONTRACT_CHECK_AUDIT">BOOST_CONTRACT_CHECK_AUDIT</a></code>
893 and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_CHECK_AXIOM.html" title="Macro BOOST_CONTRACT_CHECK_AXIOM">BOOST_CONTRACT_CHECK_AXIOM</a></code>
894 are similar to <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45395000817520.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
895 and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45395027441616.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
896 but they are used to program audit and axiom levels for implementation checks
897 instead of assertions (see <a class="link" href="advanced.html#boost_contract.advanced.implementation_checks" title="Implementation Checks">Implementation
901 For example, <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45395000817520.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
902 can be used to program computationally expensive assertions (see <a href="../../../example/features/assertion_level.cpp" target="_top"><code class="literal">assertion_level.cpp</code></a>):
906 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">RandomIter</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
907 <span class="identifier">RandomIter</span> <span class="identifier">random_binary_search</span><span class="special">(</span><span class="identifier">RandomIter</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">RandomIter</span> <span class="identifier">last</span><span class="special">,</span>
908 <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
909 <span class="identifier">RandomIter</span> <span class="identifier">result</span><span class="special">;</span>
910 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
911 <span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span>
912 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">first</span> <span class="special"><=</span> <span class="identifier">last</span><span class="special">);</span> <span class="comment">// Default, not expensive.</span>
913 <span class="comment">// Expensive O(n) assertion (use AXIOM if prohibitive instead).</span>
914 <span class="identifier">BOOST_CONTRACT_ASSERT_AUDIT</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_sorted</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">));</span>
915 <span class="special">})</span>
916 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
917 <span class="keyword">if</span><span class="special">(</span><span class="identifier">result</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(*</span><span class="identifier">result</span> <span class="special">==</span> <span class="identifier">value</span><span class="special">);</span>
918 <span class="special">})</span>
919 <span class="special">;</span>
921 <span class="comment">/* ... */</span>
926 Similarly, <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_AUDITS.html" title="Macro BOOST_CONTRACT_AUDITS">BOOST_CONTRACT_AUDITS</a></code>
927 can be used to disable expensive old value copies and related assertions
928 that use them (see <a href="../../../example/features/assertion_level.cpp" target="_top"><code class="literal">assertion_level.cpp</code></a>):
932 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
933 <span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
939 <pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
940 <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">vector</span><span class="special">&</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">{</span>
941 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="identifier">vector</span><span class="special">></span> <span class="identifier">old_me</span><span class="special">,</span> <span class="identifier">old_other</span><span class="special">;</span>
942 <span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_CONTRACT_AUDITS</span>
943 <span class="identifier">old_me</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(*</span><span class="keyword">this</span><span class="special">);</span>
944 <span class="identifier">old_other</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">other</span><span class="special">);</span>
945 <span class="preprocessor">#endif</span> <span class="comment">// Else, skip old value copies...</span>
946 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
947 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
948 <span class="comment">// ...and also skip related assertions.</span>
949 <span class="identifier">BOOST_CONTRACT_ASSERT_AUDIT</span><span class="special">(*</span><span class="keyword">this</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_other</span><span class="special">);</span>
950 <span class="identifier">BOOST_CONTRACT_ASSERT_AUDIT</span><span class="special">(</span><span class="identifier">other</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_me</span><span class="special">);</span>
951 <span class="special">})</span>
952 <span class="special">;</span>
954 <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">vect_</span><span class="special">);</span>
955 <span class="special">}</span>
961 <pre class="programlisting"> <span class="comment">/* ... */</span>
963 <span class="keyword">private</span><span class="special">:</span>
964 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">vect_</span><span class="special">;</span>
965 <span class="special">};</span>
970 The condition passed to <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45395027441616.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
971 is compiled but not actually evaluated at run-time so this macro can be used
972 to program computationally prohibitive assertions but also assertions that
973 cannot actually be programmed in C++ using functions that are declared but
974 left undefined. For example, (see <a href="../../../example/features/assertion_level.cpp" target="_top"><code class="literal">assertion_level.cpp</code></a>):
978 <pre class="programlisting"><span class="comment">// If valid iterator range (cannot implement in C++ but OK to use in AXIOM).</span>
979 <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">></span>
980 <span class="keyword">bool</span> <span class="identifier">valid</span><span class="special">(</span><span class="identifier">Iter</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iter</span> <span class="identifier">last</span><span class="special">);</span> <span class="comment">// Only declared, not actually defined.</span>
986 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
987 <span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
993 <pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
994 <span class="identifier">iterator</span> <span class="identifier">insert</span><span class="special">(</span><span class="identifier">iterator</span> <span class="identifier">where</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
995 <span class="identifier">iterator</span> <span class="identifier">result</span><span class="special">;</span>
996 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">></span> <span class="identifier">old_capacity</span> <span class="special">=</span>
997 <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">capacity</span><span class="special">());</span>
998 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
999 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
1000 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">>=</span> <span class="special">*</span><span class="identifier">old_capacity</span><span class="special">);</span>
1001 <span class="keyword">if</span><span class="special">(</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">></span> <span class="special">*</span><span class="identifier">old_capacity</span><span class="special">)</span> <span class="special">{</span>
1002 <span class="identifier">BOOST_CONTRACT_ASSERT_AXIOM</span><span class="special">(!</span><span class="identifier">valid</span><span class="special">(</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">end</span><span class="special">()));</span>
1003 <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
1004 <span class="identifier">BOOST_CONTRACT_ASSERT_AXIOM</span><span class="special">(!</span><span class="identifier">valid</span><span class="special">(</span><span class="identifier">where</span><span class="special">,</span> <span class="identifier">end</span><span class="special">()));</span>
1005 <span class="special">}</span>
1006 <span class="special">})</span>
1007 <span class="special">;</span>
1009 <span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">where</span><span class="special">,</span> <span class="identifier">value</span><span class="special">);</span>
1010 <span class="special">}</span>
1016 <pre class="programlisting"> <span class="comment">/* ... */</span>
1018 <span class="keyword">private</span><span class="special">:</span>
1019 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">vect_</span><span class="special">;</span>
1020 <span class="special">};</span>
1025 In addition to these assertion levels that are predefined by this library,
1026 programmers are free to define their own. For example, the following macro
1027 could be used to program and selectively disable assertions that have exponential
1028 computational complexity <code class="computeroutput"><span class="identifier">O</span><span class="special">(</span><span class="identifier">e</span><span class="special">^</span><span class="identifier">n</span><span class="special">)</span></code>:
1030 <pre class="programlisting"><span class="preprocessor">#ifdef</span> <span class="identifier">EXPONENTIALLY_COMPLEX_ASSERTIONS</span>
1031 <span class="comment">// Following will compile and also evaluate `cond`.</span>
1032 <span class="preprocessor">#define</span> <span class="identifier">ASSERT_EXP</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</span>
1033 <span class="preprocessor">#else</span>
1034 <span class="comment">// Following will compile but never actually evaluate `cond`.</span>
1035 <span class="preprocessor">#define</span> <span class="identifier">ASSERT_EXP</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="keyword">true</span> <span class="special">||</span> <span class="special">(</span><span class="identifier">cond</span><span class="special">))</span>
1036 <span class="preprocessor">#endif</span>
1038 <span class="special">...</span>
1040 <span class="identifier">ASSERT_EXP</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>some-exponentially-complex-boolean-condition</em></span></code><span class="special">);</span>
1043 <div class="section">
1044 <div class="titlepage"><div><div><h3 class="title">
1045 <a name="boost_contract.extras.disable_contract_checking"></a><a class="link" href="extras.html#boost_contract.extras.disable_contract_checking" title="Disable Contract Checking">Disable
1046 Contract Checking</a>
1047 </h3></div></div></div>
1049 Checking contracts adds run-time overhead and can slow down program execution
1050 (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.benefits_and_costs" title="Benefits and Costs">Benefits
1051 and Costs</a>). Therefore, programmers can define any combination of the
1052 following macros (<code class="computeroutput"><span class="special">-</span><span class="identifier">D</span></code>
1053 option in Clang and GCC, <code class="computeroutput"><span class="special">/</span><span class="identifier">D</span></code>
1054 option in MSVC, etc.) to instruct this library to not check specific groups
1055 of contract conditions at run-time:
1057 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1058 <li class="listitem">
1059 Define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999662416.html" title="Macro BOOST_CONTRACT_NO_PRECONDITIONS">BOOST_CONTRACT_NO_PRECONDITIONS</a></code>
1060 to not check preconditions.
1062 <li class="listitem">
1063 Define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999656032.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>
1064 to not check postconditions.
1066 <li class="listitem">
1067 Define <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>
1068 to not check exception guarantees.
1070 <li class="listitem">
1071 Define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999637264.html" title="Macro BOOST_CONTRACT_NO_ENTRY_INVARIANTS">BOOST_CONTRACT_NO_ENTRY_INVARIANTS</a></code>
1072 to not check class invariants at call entry.
1074 <li class="listitem">
1075 Define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999629648.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>
1076 to not check class invariants at call exit.
1078 <li class="listitem">
1079 Or, define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999622032.html" title="Macro BOOST_CONTRACT_NO_INVARIANTS">BOOST_CONTRACT_NO_INVARIANTS</a></code>
1080 to not check class invariants at both call entry and exit. (This is provided
1081 for convenience, it is equivalent to defining both <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999637264.html" title="Macro BOOST_CONTRACT_NO_ENTRY_INVARIANTS">BOOST_CONTRACT_NO_ENTRY_INVARIANTS</a></code>
1082 and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999629648.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>.)
1084 <li class="listitem">
1085 Define <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_CHECKS.html" title="Macro BOOST_CONTRACT_NO_CHECKS">BOOST_CONTRACT_NO_CHECKS</a></code>
1086 to not evaluate implementation checks.
1089 <div class="note"><table border="0" summary="Note">
1091 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1092 <th align="left">Note</th>
1094 <tr><td align="left" valign="top"><p>
1095 Old values can be used by both postconditions and exception guarantees
1096 so it is necessary to define both <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999656032.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>
1097 and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>
1098 to disable old value copies.
1102 By default, none of these macros are defined so this library checks all contracts.
1103 When these macros are defined by the user, the implementation code of this
1104 library is internally optimized to minimize as much as possible any run-time
1105 and compile-time overhead associated with checking and compiling contracts
1106 (see <a class="link" href="extras.html#boost_contract.extras.disable_contract_compilation__macro_interface_" title="Disable Contract Compilation (Macro Interface)">Disable
1107 Contract Compilation</a> for techniques to completely remove any run-time
1108 and compile-time overheads associated with contract code).
1111 For example, programmers could decide to check all contracts during early
1112 development builds, but later check only preconditions and maybe entry invariants
1113 for release builds by defining <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999656032.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>,
1114 <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>,
1115 <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999629648.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>,
1116 and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_CHECKS.html" title="Macro BOOST_CONTRACT_NO_CHECKS">BOOST_CONTRACT_NO_CHECKS</a></code>.
1119 <div class="section">
1120 <div class="titlepage"><div><div><h3 class="title">
1121 <a name="boost_contract.extras.disable_contract_compilation__macro_interface_"></a><a class="link" href="extras.html#boost_contract.extras.disable_contract_compilation__macro_interface_" title="Disable Contract Compilation (Macro Interface)">Disable
1122 Contract Compilation (Macro Interface)</a>
1123 </h3></div></div></div>
1125 This library provides macros that can be used to completely disable compile-time
1126 and run-time overhead introduced by contracts but at the cost of manually
1127 programming <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> statements around contract code:
1129 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1130 <li class="listitem">
1131 This library defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999605408.html" title="Macro BOOST_CONTRACT_NO_CONSTRUCTORS">BOOST_CONTRACT_NO_CONSTRUCTORS</a></code>
1132 when contract checking is disabled for constructors.
1134 <li class="listitem">
1135 This library defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999594544.html" title="Macro BOOST_CONTRACT_NO_DESTRUCTORS">BOOST_CONTRACT_NO_DESTRUCTORS</a></code>
1136 when contract checking is disabled for destructors.
1138 <li class="listitem">
1139 This library defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999586272.html" title="Macro BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</a></code>
1140 when contract checking is disabled for public functions.
1142 <li class="listitem">
1143 This library defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999577072.html" title="Macro BOOST_CONTRACT_NO_FUNCTIONS">BOOST_CONTRACT_NO_FUNCTIONS</a></code>
1144 when contract checking is disabled for (non-public and non-member) functions.
1146 <li class="listitem">
1147 This library defines <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_OLDS.html" title="Macro BOOST_CONTRACT_NO_OLDS">BOOST_CONTRACT_NO_OLDS</a></code>
1148 when old value copies are disabled.
1150 <li class="listitem">
1151 This library defines <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_ALL.html" title="Macro BOOST_CONTRACT_NO_ALL">BOOST_CONTRACT_NO_ALL</a></code>
1152 when all contracts above and also implementation checks (see <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_CHECKS.html" title="Macro BOOST_CONTRACT_NO_CHECKS">BOOST_CONTRACT_NO_CHECKS</a></code>)
1157 These macros are not configuration macros and they should not be defined
1158 directly by programmers (otherwise this library will generate compile-time
1159 errors). Instead, these macros are automatically defined by this library
1160 when programmers define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999662416.html" title="Macro BOOST_CONTRACT_NO_PRECONDITIONS">BOOST_CONTRACT_NO_PRECONDITIONS</a></code>,
1161 <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999656032.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>,
1162 <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>,
1163 <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999622032.html" title="Macro BOOST_CONTRACT_NO_INVARIANTS">BOOST_CONTRACT_NO_INVARIANTS</a></code>
1164 (or <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999637264.html" title="Macro BOOST_CONTRACT_NO_ENTRY_INVARIANTS">BOOST_CONTRACT_NO_ENTRY_INVARIANTS</a></code>
1165 and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999629648.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>),
1166 and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_CHECKS.html" title="Macro BOOST_CONTRACT_NO_CHECKS">BOOST_CONTRACT_NO_CHECKS</a></code>
1167 (see <a class="link" href="extras.html#boost_contract.extras.disable_contract_checking" title="Disable Contract Checking">Disable
1168 Contract Checking</a>).
1171 Alternatively, this library provides a macro-based interface defined in
1172 <code class="computeroutput"><a class="link" href="../reference.html#header.boost.contract_macro_hpp" title="Header <boost/contract_macro.hpp>">boost/contract_macro.hpp</a></code>
1173 that can also be used to completely disable compile-time and run-time overheads
1174 introduced by contracts but without the burden of manually writing the <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> statements. For example, the following
1175 code shows how to use both the <code class="computeroutput"><a class="link" href="../reference.html#header.boost.contract_macro_hpp" title="Header <boost/contract_macro.hpp>">boost/contract_macro.hpp</a></code>
1176 macro interface and the <code class="computeroutput"><span class="preprocessor">#ifndef</span>
1177 <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
1178 statements to completely disable compile-time and run-time overheads for
1179 non-member function contracts (see <a href="../../../example/features/ifdef_macro.cpp" target="_top"><code class="literal">ifdef_macro.cpp</code></a>
1180 and <a href="../../../example/features/ifdef.cpp" target="_top"><code class="literal">ifdef.cpp</code></a>):
1182 <div class="informaltable"><table class="table">
1195 <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> Statements
1203 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Use macro interface to completely disable contract code compilation.</span>
1204 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">contract_macro</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
1206 <span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
1207 <span class="keyword">int</span> <span class="identifier">result</span><span class="special">;</span>
1208 <span class="identifier">BOOST_CONTRACT_OLD_PTR</span><span class="special">(</span><span class="keyword">int</span><span class="special">)(</span><span class="identifier">old_x</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
1209 <span class="identifier">BOOST_CONTRACT_FUNCTION</span><span class="special">()</span>
1210 <span class="identifier">BOOST_CONTRACT_PRECONDITION</span><span class="special">([&]</span> <span class="special">{</span>
1211 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">max</span><span class="special">());</span>
1212 <span class="special">})</span>
1213 <span class="identifier">BOOST_CONTRACT_POSTCONDITION</span><span class="special">([&]</span> <span class="special">{</span>
1214 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
1215 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
1216 <span class="special">})</span>
1217 <span class="special">;</span>
1219 <span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">++;</span>
1220 <span class="special">}</span>
1228 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Use #ifdef to completely disable contract code compilation.</span>
1229 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">contract</span><span class="special">/</span><span class="identifier">core</span><span class="special">/</span><span class="identifier">config</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
1230 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_ALL</span>
1231 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">contract</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
1232 <span class="preprocessor">#endif</span>
1234 <span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
1235 <span class="keyword">int</span> <span class="identifier">result</span><span class="special">;</span>
1236 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_OLDS</span>
1237 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
1238 <span class="preprocessor">#endif</span>
1239 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_FUNCTIONS</span>
1240 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
1241 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PRECONDITIONS</span>
1242 <span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span>
1243 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">max</span><span class="special">());</span>
1244 <span class="special">})</span>
1245 <span class="preprocessor">#endif</span>
1246 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_POSTCONDITIONS</span>
1247 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
1248 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
1249 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
1250 <span class="special">})</span>
1251 <span class="preprocessor">#endif</span>
1252 <span class="special">;</span>
1253 <span class="preprocessor">#endif</span>
1255 <span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">++;</span>
1256 <span class="special">}</span>
1264 The same can be done to disable contract code complication for private and
1265 protected functions. The <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394998674080.html" title="Macro BOOST_CONTRACT_OLD_PTR_IF_COPYABLE">BOOST_CONTRACT_OLD_PTR_IF_COPYABLE</a></code>
1266 macro is provided to handle non-copyable old value types (similar to <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>).
1269 For constructors, destructors, and public functions the <code class="computeroutput"><a class="link" href="../reference.html#header.boost.contract_macro_hpp" title="Header <boost/contract_macro.hpp>">boost/contract_macro.hpp</a></code>
1270 macro interface and the <code class="computeroutput"><span class="preprocessor">#ifndef</span>
1271 <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
1272 statements can be used as follow (see <a href="../../../example/features/ifdef_macro.cpp" target="_top"><code class="literal">ifdef_macro.cpp</code></a>
1273 and <a href="../../../example/features/ifdef.cpp" target="_top"><code class="literal">ifdef.cpp</code></a>):
1275 <div class="informaltable"><table class="table">
1288 <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> Statements
1296 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">class</span> <span class="identifier">integers</span>
1297 <span class="preprocessor">#define</span> <span class="identifier">BASES</span> <span class="keyword">public</span> <span class="identifier">pushable</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span>
1298 <span class="special">:</span>
1299 <span class="comment">// Left in code (almost no overhead).</span>
1300 <span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">integers</span><span class="special">>,</span>
1301 <span class="identifier">BASES</span>
1302 <span class="special">{</span>
1303 <span class="comment">// Followings left in code (almost no overhead).</span>
1304 <span class="keyword">friend</span> <span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">access</span><span class="special">;</span>
1306 <span class="keyword">typedef</span> <span class="identifier">BOOST_CONTRACT_BASE_TYPES</span><span class="special">(</span><span class="identifier">BASES</span><span class="special">)</span> <span class="identifier">base_types</span><span class="special">;</span>
1307 <span class="preprocessor">#undef</span> <span class="identifier">BASES</span>
1309 <span class="identifier">BOOST_CONTRACT_INVARIANT</span><span class="special">({</span>
1310 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><=</span> <span class="identifier">capacity</span><span class="special">());</span>
1311 <span class="special">})</span>
1313 <span class="keyword">public</span><span class="special">:</span>
1314 <span class="identifier">integers</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">from</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">to</span><span class="special">)</span> <span class="special">:</span>
1315 <span class="identifier">BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION</span><span class="special">(</span><span class="identifier">integers</span><span class="special">)([&]</span> <span class="special">{</span>
1316 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">from</span> <span class="special"><=</span> <span class="identifier">to</span><span class="special">);</span>
1317 <span class="special">}),</span>
1318 <span class="identifier">vect_</span><span class="special">(</span><span class="identifier">to</span> <span class="special">-</span> <span class="identifier">from</span> <span class="special">+</span> <span class="number">1</span><span class="special">)</span>
1319 <span class="special">{</span>
1320 <span class="identifier">BOOST_CONTRACT_CONSTRUCTOR</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
1321 <span class="identifier">BOOST_CONTRACT_POSTCONDITION</span><span class="special">([&]</span> <span class="special">{</span>
1322 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="keyword">int</span><span class="special">(</span><span class="identifier">size</span><span class="special">())</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">to</span> <span class="special">-</span> <span class="identifier">from</span> <span class="special">+</span> <span class="number">1</span><span class="special">));</span>
1323 <span class="special">})</span>
1324 <span class="special">;</span>
1326 <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">from</span><span class="special">;</span> <span class="identifier">x</span> <span class="special"><=</span> <span class="identifier">to</span><span class="special">;</span> <span class="special">++</span><span class="identifier">x</span><span class="special">)</span> <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="identifier">x</span> <span class="special">-</span> <span class="identifier">from</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span>
1327 <span class="special">}</span>
1329 <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">integers</span><span class="special">()</span> <span class="special">{</span>
1330 <span class="identifier">BOOST_CONTRACT_DESTRUCTOR</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span> <span class="comment">// Check invariants.</span>
1331 <span class="special">}</span>
1333 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span>
1334 <span class="keyword">int</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span>
1335 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span> <span class="comment">// Left in code (almost no overhead).</span>
1336 <span class="special">)</span> <span class="comment">/* override */</span> <span class="special">{</span>
1337 <span class="identifier">BOOST_CONTRACT_OLD_PTR</span><span class="special">(</span><span class="keyword">unsigned</span><span class="special">)(</span><span class="identifier">old_size</span><span class="special">);</span>
1338 <span class="identifier">BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE</span><span class="special">(</span><span class="identifier">override_push_back</span><span class="special">)(</span>
1339 <span class="identifier">v</span><span class="special">,</span> <span class="special">&</span><span class="identifier">integers</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">x</span><span class="special">)</span>
1340 <span class="identifier">BOOST_CONTRACT_PRECONDITION</span><span class="special">([&]</span> <span class="special">{</span>
1341 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><</span> <span class="identifier">max_size</span><span class="special">());</span>
1342 <span class="special">})</span>
1343 <span class="identifier">BOOST_CONTRACT_OLD</span><span class="special">([&]</span> <span class="special">{</span>
1344 <span class="identifier">old_size</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">size</span><span class="special">());</span>
1345 <span class="special">})</span>
1346 <span class="identifier">BOOST_CONTRACT_POSTCONDITION</span><span class="special">([&]</span> <span class="special">{</span>
1347 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
1348 <span class="special">})</span>
1349 <span class="identifier">BOOST_CONTRACT_EXCEPT</span><span class="special">([&]</span> <span class="special">{</span>
1350 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span><span class="special">);</span>
1351 <span class="special">})</span>
1352 <span class="special">;</span>
1354 <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
1355 <span class="special">}</span>
1357 <span class="keyword">private</span><span class="special">:</span>
1358 <span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">push_back</span><span class="special">)</span> <span class="comment">// Left in code (almost no overhead).</span>
1360 <span class="comment">/* ... */</span>
1368 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">class</span> <span class="identifier">integers</span>
1369 <span class="preprocessor">#define</span> <span class="identifier">BASES</span> <span class="keyword">public</span> <span class="identifier">pushable</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span>
1370 <span class="special">:</span>
1371 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PRECONDITIONS</span>
1372 <span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">integers</span><span class="special">>,</span> <span class="identifier">BASES</span>
1373 <span class="preprocessor">#else</span>
1374 <span class="identifier">BASES</span>
1375 <span class="preprocessor">#endif</span>
1376 <span class="special">{</span>
1377 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_ALL</span>
1378 <span class="keyword">friend</span> <span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">access</span><span class="special">;</span>
1379 <span class="preprocessor">#endif</span>
1381 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</span>
1382 <span class="keyword">typedef</span> <span class="identifier">BOOST_CONTRACT_BASE_TYPES</span><span class="special">(</span><span class="identifier">BASES</span><span class="special">)</span> <span class="identifier">base_types</span><span class="special">;</span>
1383 <span class="preprocessor">#endif</span>
1384 <span class="preprocessor">#undef</span> <span class="identifier">BASES</span>
1386 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_INVARIANTS</span>
1387 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
1388 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><=</span> <span class="identifier">capacity</span><span class="special">());</span>
1389 <span class="special">}</span>
1390 <span class="preprocessor">#endif</span>
1392 <span class="keyword">public</span><span class="special">:</span>
1393 <span class="identifier">integers</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">from</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">to</span><span class="special">)</span> <span class="special">:</span>
1394 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PRECONDITIONS</span>
1395 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">integers</span><span class="special">>([&]</span> <span class="special">{</span>
1396 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">from</span> <span class="special"><=</span> <span class="identifier">to</span><span class="special">);</span>
1397 <span class="special">}),</span>
1398 <span class="preprocessor">#endif</span>
1399 <span class="identifier">vect_</span><span class="special">(</span><span class="identifier">to</span> <span class="special">-</span> <span class="identifier">from</span> <span class="special">+</span> <span class="number">1</span><span class="special">)</span>
1400 <span class="special">{</span>
1401 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_CONSTRUCTORS</span>
1402 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
1403 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_POSTCONDITIONS</span>
1404 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
1405 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="keyword">int</span><span class="special">(</span><span class="identifier">size</span><span class="special">())</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">to</span> <span class="special">-</span> <span class="identifier">from</span> <span class="special">+</span> <span class="number">1</span><span class="special">));</span>
1406 <span class="special">})</span>
1407 <span class="preprocessor">#endif</span>
1408 <span class="special">;</span>
1409 <span class="preprocessor">#endif</span>
1411 <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">from</span><span class="special">;</span> <span class="identifier">x</span> <span class="special"><=</span> <span class="identifier">to</span><span class="special">;</span> <span class="special">++</span><span class="identifier">x</span><span class="special">)</span> <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="identifier">x</span> <span class="special">-</span> <span class="identifier">from</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span>
1412 <span class="special">}</span>
1414 <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">integers</span><span class="special">()</span> <span class="special">{</span>
1415 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_DESTRUCTORS</span>
1416 <span class="comment">// Check invariants.</span>
1417 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">destructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
1418 <span class="preprocessor">#endif</span>
1419 <span class="special">}</span>
1421 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span>
1422 <span class="keyword">int</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span>
1423 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</span>
1424 <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span>
1425 <span class="preprocessor">#endif</span>
1426 <span class="special">)</span> <span class="comment">/* override */</span> <span class="special">{</span>
1427 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_OLDS</span>
1428 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">></span> <span class="identifier">old_size</span><span class="special">;</span>
1429 <span class="preprocessor">#endif</span>
1430 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</span>
1431 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span>
1432 <span class="identifier">override_push_back</span><span class="special">>(</span><span class="identifier">v</span><span class="special">,</span> <span class="special">&</span><span class="identifier">integers</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">x</span><span class="special">)</span>
1433 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PRECONDITIONS</span>
1434 <span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span>
1435 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><</span> <span class="identifier">max_size</span><span class="special">());</span>
1436 <span class="special">})</span>
1437 <span class="preprocessor">#endif</span>
1438 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_OLDS</span>
1439 <span class="special">.</span><span class="identifier">old</span><span class="special">([&]</span> <span class="special">{</span>
1440 <span class="identifier">old_size</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">size</span><span class="special">());</span>
1441 <span class="special">})</span>
1442 <span class="preprocessor">#endif</span>
1443 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_POSTCONDITIONS</span>
1444 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
1445 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
1446 <span class="special">})</span>
1447 <span class="preprocessor">#endif</span>
1448 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_EXCEPTS</span>
1449 <span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span>
1450 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span><span class="special">);</span>
1451 <span class="special">})</span>
1452 <span class="preprocessor">#endif</span>
1453 <span class="special">;</span>
1454 <span class="preprocessor">#endif</span>
1456 <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
1457 <span class="special">}</span>
1459 <span class="keyword">private</span><span class="special">:</span>
1460 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</span>
1461 <span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">push_back</span><span class="special">)</span>
1462 <span class="preprocessor">#endif</span>
1464 <span class="comment">/* ... */</span>
1472 Static and volatile class invariants can be programmed using <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394998621472.html" title="Macro BOOST_CONTRACT_STATIC_INVARIANT">BOOST_CONTRACT_STATIC_INVARIANT</a></code>
1473 and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394998635328.html" title="Macro BOOST_CONTRACT_INVARIANT_VOLATILE">BOOST_CONTRACT_INVARIANT_VOLATILE</a></code>
1474 respectively (these macros expand code equivalent to the <code class="computeroutput"><span class="keyword">static</span>
1475 <span class="keyword">void</span> <span class="identifier">BOOST_CONTRACT_STATIC_INVARIANT_FUNC</span><span class="special">()</span></code> and <code class="computeroutput"><span class="keyword">void</span>
1476 <span class="identifier">BOOST_CONTRACT_INVARIANT_FUNC</span><span class="special">()</span>
1477 <span class="keyword">const</span> <span class="keyword">volatile</span></code>
1481 The <code class="computeroutput"><a class="link" href="../reference.html#header.boost.contract_macro_hpp" title="Header <boost/contract_macro.hpp>">boost/contract_macro.hpp</a></code>
1482 macro interface is usually preferred because more concise and easier to use
1483 than programming <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
1484 statements by hand. However, C++ macros expand on a single line of code and
1485 that can make compiler errors less useful when using this macro interface
1486 plus all contract assertions within a given set of preconditions, postconditions,
1487 exception guarantees, and class invariants will list the same line number
1488 in error messages when assertions fail at run-time (but error messages still
1489 list the assertion code and that should still allow programmers to identify
1490 the specific assertion that failed). Finally, the macro interface leaves
1491 a bit of contract decorations in the code but that should add no measurable
1492 compile-time or run-time overhead (specifically, extra <code class="computeroutput"><a class="link" href="../boost/contract/virtual_.html" title="Class virtual_">boost::contract::virtual_</a></code><code class="computeroutput"><span class="special">*</span></code> parameters, calls to <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
1493 default constructor which does nothing, <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
1494 <code class="computeroutput"><span class="keyword">typedef</span></code>s, and <code class="computeroutput"><a class="link" href="../boost/contract/access.html" title="Class access">boost::contract::access</a></code>
1495 friendships are left in user code even when contracts are disabled unless
1496 <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> statements are used).
1499 Disabling contract as shown in <a class="link" href="extras.html#boost_contract.extras.disable_contract_checking" title="Disable Contract Checking">Disable
1500 Contract Checking</a> leaves the overhead of compiling contract code plus
1501 some small run-time overhead due to the initialization of old value pointers
1502 (even if those will be all null and no old value will be actually copied),
1503 the calls to the contract functions used to initialize <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
1504 and <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
1505 (even if those calls will be internally optimized by this library to essentially
1506 do nothing), etc. For truly performance critical code for which even such
1507 small run-time overhead might not be acceptable, the macro interface (or
1508 the <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> statements) can be used to completely
1509 disable compile-time and run-time overheads of contracts. However, for such
1510 performance critical code even the overhead of checking simple preconditions
1511 might be too much so it might be best to not program contracts at all.
1514 Usually, if the overhead of checking preconditions and other assertions is
1515 already considered acceptable for an application then the compile-time overhead
1516 of contracts should not represent an issue and it should be sufficient to
1517 disable contract checking at run-time as indicated in <a class="link" href="extras.html#boost_contract.extras.disable_contract_checking" title="Disable Contract Checking">Disable
1518 Contract Checking</a> (without a real need to use the <code class="computeroutput"><a class="link" href="../reference.html#header.boost.contract_macro_hpp" title="Header <boost/contract_macro.hpp>">boost/contract_macro.hpp</a></code>
1519 macro interface or the <code class="computeroutput"><span class="preprocessor">#ifndef</span>
1520 <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
1521 statements in most cases).
1524 <div class="section">
1525 <div class="titlepage"><div><div><h3 class="title">
1526 <a name="boost_contract.extras.separate_body_implementation"></a><a class="link" href="extras.html#boost_contract.extras.separate_body_implementation" title="Separate Body Implementation">Separate
1527 Body Implementation</a>
1528 </h3></div></div></div>
1530 Contracts are part of the program specifications and not of its implementation
1531 (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.specifications_vs__implementation" title="Specifications vs. Implementation">Specifications
1532 vs. Implementation</a>). However, this library uses function definitions
1533 to program contracts so contract code appears together with the function
1534 implementation code. This is not ideal (even if contracts programmed using
1535 this library will always appear at the very beginning of the function definition
1536 so programmers will easily be able to distinguish contract code from the
1537 rest of the function implementation code so this might not be real limitation
1541 In some cases, it might be desirable to completely separate the contract
1542 code from the function implementation code. For example, this could be necessary
1543 for software that ships only header files and compiled object files to its
1544 users. If contracts are programmed in function definitions that are compiled
1545 in the object files, users will not be able to see the contract code to understand
1546 semantics and usage of the functions (again, this might not be a real problem
1547 in practice for example if contracts are already somehow extracted from the
1548 source code by some tool and presented as part of the documentation of the
1552 In any case, when it is truly important to separate contracts from function
1553 implementation code, function implementations can be programmed in extra
1554 <span class="emphasis"><em>body functions</em></span> (here named <code class="computeroutput"><span class="special">...</span><span class="identifier">_body</span></code>, but any other naming scheme could
1555 be used) that are compiled in object files. Function definitions that remain
1556 in header files instead will contain just contract code followed by calls
1557 to the extra body functions. This technique allows to keep the contract code
1558 in header files while separating the implementation code to source and object
1559 files. However, this adds the overhead of manually programming an extra function
1560 declaration for each body function (plus the limitation that constructor
1561 member initialization lists must be programmed in header files because that
1562 is where constructors need to be defined to list constructor contract code).
1563 <a href="#ftn.boost_contract.extras.separate_body_implementation.f0" class="footnote" name="boost_contract.extras.separate_body_implementation.f0"><sup class="footnote">[77]</sup></a>
1566 For example, the following header file only contains function declarations,
1567 contract code, and constructor member initializations, but it does not contain
1568 the code implementing the function bodies (see <a href="../../../example/features/separate_body.hpp" target="_top"><code class="literal">separate_body.hpp</code></a>):
1572 <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">iarray</span> <span class="special">:</span>
1573 <span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">iarray</span><span class="special">></span> <span class="special">{</span>
1574 <span class="keyword">public</span><span class="special">:</span>
1575 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
1576 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><=</span> <span class="identifier">capacity</span><span class="special">());</span>
1577 <span class="special">}</span>
1579 <span class="keyword">explicit</span> <span class="identifier">iarray</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">max</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">count</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">:</span>
1580 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">iarray</span><span class="special">>([&]</span> <span class="special">{</span>
1581 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">count</span> <span class="special"><=</span> <span class="identifier">max</span><span class="special">);</span>
1582 <span class="special">}),</span>
1583 <span class="comment">// Still, member initializations must be here.</span>
1584 <span class="identifier">values_</span><span class="special">(</span><span class="keyword">new</span> <span class="keyword">int</span><span class="special">[</span><span class="identifier">max</span><span class="special">]),</span>
1585 <span class="identifier">capacity_</span><span class="special">(</span><span class="identifier">max</span><span class="special">)</span>
1586 <span class="special">{</span>
1587 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
1588 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
1589 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">max</span><span class="special">);</span>
1590 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">count</span><span class="special">);</span>
1591 <span class="special">})</span>
1592 <span class="special">;</span>
1593 <span class="identifier">constructor_body</span><span class="special">(</span><span class="identifier">max</span><span class="special">,</span> <span class="identifier">count</span><span class="special">);</span> <span class="comment">// Separate constructor body impl.</span>
1594 <span class="special">}</span>
1596 <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">iarray</span><span class="special">()</span> <span class="special">{</span>
1597 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">destructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span> <span class="comment">// Inv.</span>
1598 <span class="identifier">destructor_body</span><span class="special">();</span> <span class="comment">// Separate destructor body implementation.</span>
1599 <span class="special">}</span>
1601 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">value</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span>
1602 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">></span> <span class="identifier">old_size</span> <span class="special">=</span>
1603 <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">size</span><span class="special">());</span>
1604 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="keyword">this</span><span class="special">)</span>
1605 <span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span>
1606 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><</span> <span class="identifier">capacity</span><span class="special">());</span>
1607 <span class="special">})</span>
1608 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
1609 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
1610 <span class="special">})</span>
1611 <span class="special">;</span>
1612 <span class="identifier">push_back_body</span><span class="special">(</span><span class="identifier">value</span><span class="special">);</span> <span class="comment">// Separate member function body implementation.</span>
1613 <span class="special">}</span>
1615 <span class="keyword">private</span><span class="special">:</span>
1616 <span class="comment">// Contracts in class declaration (above), but body implementations are not.</span>
1617 <span class="keyword">void</span> <span class="identifier">constructor_body</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">max</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">count</span><span class="special">);</span>
1618 <span class="keyword">void</span> <span class="identifier">destructor_body</span><span class="special">();</span>
1619 <span class="keyword">void</span> <span class="identifier">push_back_body</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">value</span><span class="special">);</span>
1621 <span class="comment">/* ... */</span>
1626 Instead, the function bodies are implemented in a separate source file (see
1627 <a href="../../../example/features/separate_body.cpp" target="_top"><code class="literal">separate_body.cpp</code></a>):
1631 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">iarray</span><span class="special">::</span><span class="identifier">constructor_body</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">max</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">count</span><span class="special">)</span> <span class="special">{</span>
1632 <span class="keyword">for</span><span class="special">(</span><span class="keyword">unsigned</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="identifier">count</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">i</span><span class="special">]</span> <span class="special">=</span> <span class="keyword">int</span><span class="special">();</span>
1633 <span class="identifier">size_</span> <span class="special">=</span> <span class="identifier">count</span><span class="special">;</span>
1634 <span class="special">}</span>
1636 <span class="keyword">void</span> <span class="identifier">iarray</span><span class="special">::</span><span class="identifier">destructor_body</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">delete</span><span class="special">[]</span> <span class="identifier">values_</span><span class="special">;</span> <span class="special">}</span>
1638 <span class="keyword">void</span> <span class="identifier">iarray</span><span class="special">::</span><span class="identifier">push_back_body</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">values_</span><span class="special">[</span><span class="identifier">size_</span><span class="special">++]</span> <span class="special">=</span> <span class="identifier">value</span><span class="special">;</span> <span class="special">}</span>
1640 <span class="comment">/* ... */</span>
1645 The same technique can be used for non-member, private, and protected functions,
1648 <div class="note"><table border="0" summary="Note">
1650 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1651 <th align="left">Note</th>
1653 <tr><td align="left" valign="top">
1655 When contracts are programmed only in <code class="literal">.cpp</code> files and
1656 also all this library headers are <code class="computeroutput"><span class="preprocessor">#include</span></code>d
1657 only from <code class="literal">.cpp</code> files, then these <code class="literal">.cpp</code>
1658 files can be compiled disabling specific contract checking (for example,
1659 <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999656032.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>,
1660 <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>,
1661 and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394999629648.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>,
1662 see <a class="link" href="extras.html#boost_contract.extras.disable_contract_checking" title="Disable Contract Checking">Disable
1663 Contract Checking</a>). Then the code in these <code class="literal">.cpp</code>
1664 files will always have such contract checking disabled even when linked
1665 to some other user code that might have been compiled with a different
1666 set of contracts disabled (i.e., a different set of <code class="computeroutput"><span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> macros defined). This technique might
1667 be useful to ship compiled object files (e.g., for a library) that will
1668 never check some contracts (e.g., postconditions, exception guarantees,
1669 and exit invariants) regardless of the definition of the <code class="computeroutput"><span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
1670 macros used to compile code that links against the shipped object files.
1673 On the flip side, if contracts are programmed only in header files (e.g.,
1674 using extra <code class="computeroutput"><span class="special">...</span><span class="identifier">_body</span></code>
1675 functions as shown in this section) and this library headers are <code class="computeroutput"><span class="preprocessor">#include</span></code>d only in these header files
1676 that are being shipped, then end users can enable or disables contract
1677 checking of the shipped code by defining the <code class="computeroutput"><span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> macros when they compile the shipped
1678 header files as part of their code. This technique might be useful in other
1679 situations when programmers that ship code want to leave it up the their
1680 end users to decide which contracts of the shipped code should be checked
1686 <div class="section">
1687 <div class="titlepage"><div><div><h3 class="title">
1688 <a name="boost_contract.extras.no_lambda_functions__no_c__11_"></a><a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
1689 Lambda Functions (No C++11)</a>
1690 </h3></div></div></div>
1692 This section shows how to use this library without C++11 lambda functions.
1693 This has some advantages:
1695 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1696 <li class="listitem">
1697 It allows to use this library on compilers that do not support C++11
1698 lambda functions (essentially most C++03 compilers with adequate support
1699 for SFINAE can be used in that case, see <a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
1700 Macros</a> to also avoid using variadic macros). <a href="#ftn.boost_contract.extras.no_lambda_functions__no_c__11_.f0" class="footnote" name="boost_contract.extras.no_lambda_functions__no_c__11_.f0"><sup class="footnote">[78]</sup></a>
1702 <li class="listitem">
1703 Contract functions (i.e., the <code class="computeroutput"><span class="special">...</span><span class="identifier">_precondition</span></code>, <code class="computeroutput"><span class="special">...</span><span class="identifier">_old</span></code>, and <code class="computeroutput"><span class="special">...</span><span class="identifier">_postcondition</span></code> functions in the example
1704 below) can be programmed to fully enforce constant-correctness and other
1705 contract requirements at compile-time (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
1706 <a href="#ftn.boost_contract.extras.no_lambda_functions__no_c__11_.f1" class="footnote" name="boost_contract.extras.no_lambda_functions__no_c__11_.f1"><sup class="footnote">[79]</sup></a>
1708 <li class="listitem">
1709 Code of the contract functions is separated from function body implementations
1710 (see <a class="link" href="extras.html#boost_contract.extras.separate_body_implementation" title="Separate Body Implementation">Separate
1711 Body Implementation</a>).
1715 However, not using C++11 lambda functions comes at the significant cost of
1716 having to manually program the extra contract functions and related boiler-plate
1717 code. For example, the header file (see <a href="../../../example/features/no_lambdas.hpp" target="_top"><code class="literal">no_lambdas.hpp</code></a>):
1721 <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">iarray</span> <span class="special">:</span>
1722 <span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">iarray</span><span class="special">></span> <span class="special">{</span>
1723 <span class="keyword">public</span><span class="special">:</span>
1724 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">static_invariant</span><span class="special">()</span> <span class="special">{</span>
1725 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
1726 <span class="special">}</span>
1728 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
1729 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><=</span> <span class="identifier">capacity</span><span class="special">());</span>
1730 <span class="special">}</span>
1732 <span class="keyword">explicit</span> <span class="identifier">iarray</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">max</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">count</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
1733 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">constructor_precondition</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">const</span> <span class="identifier">max</span><span class="special">,</span>
1734 <span class="keyword">unsigned</span> <span class="keyword">const</span> <span class="identifier">count</span><span class="special">)</span> <span class="special">{</span>
1735 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">count</span> <span class="special"><=</span> <span class="identifier">max</span><span class="special">);</span>
1736 <span class="special">}</span>
1737 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">constructor_old</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">>&</span>
1738 <span class="identifier">old_instances</span><span class="special">)</span> <span class="special">{</span>
1739 <span class="identifier">old_instances</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">instances</span><span class="special">());</span>
1740 <span class="special">}</span>
1741 <span class="keyword">void</span> <span class="identifier">constructor_postcondition</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">const</span> <span class="identifier">max</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">const</span> <span class="identifier">count</span><span class="special">,</span>
1742 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">old_instances</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
1743 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">max</span><span class="special">);</span>
1744 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">count</span><span class="special">);</span>
1745 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_instances</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
1746 <span class="special">}</span>
1748 <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">iarray</span><span class="special">();</span>
1749 <span class="keyword">void</span> <span class="identifier">destructor_old</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">>&</span> <span class="identifier">old_instances</span><span class="special">)</span>
1750 <span class="keyword">const</span> <span class="special">{</span>
1751 <span class="identifier">old_instances</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">instances</span><span class="special">());</span>
1752 <span class="special">}</span>
1753 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">destructor_postcondition</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">const</span>
1754 <span class="identifier">old_instances</span><span class="special">)</span> <span class="special">{</span>
1755 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_instances</span> <span class="special">-</span> <span class="number">1</span><span class="special">);</span>
1756 <span class="special">}</span>
1758 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">value</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
1759 <span class="keyword">void</span> <span class="identifier">push_back_precondition</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
1760 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><</span> <span class="identifier">capacity</span><span class="special">());</span>
1761 <span class="special">}</span>
1762 <span class="keyword">void</span> <span class="identifier">push_back_old</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span><span class="special">,</span>
1763 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">>&</span> <span class="identifier">old_size</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
1764 <span class="identifier">old_size</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">size</span><span class="special">());</span>
1765 <span class="special">}</span>
1766 <span class="keyword">void</span> <span class="identifier">push_back_postcondition</span><span class="special">(</span>
1767 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">old_size</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
1768 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
1769 <span class="special">}</span>
1771 <span class="keyword">unsigned</span> <span class="identifier">capacity</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
1772 <span class="keyword">unsigned</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
1774 <span class="keyword">static</span> <span class="keyword">int</span> <span class="identifier">instances</span><span class="special">();</span>
1776 <span class="keyword">private</span><span class="special">:</span>
1777 <span class="keyword">int</span><span class="special">*</span> <span class="identifier">values_</span><span class="special">;</span>
1778 <span class="keyword">unsigned</span> <span class="identifier">capacity_</span><span class="special">;</span>
1779 <span class="keyword">unsigned</span> <span class="identifier">size_</span><span class="special">;</span>
1780 <span class="keyword">static</span> <span class="keyword">int</span> <span class="identifier">instances_</span><span class="special">;</span>
1781 <span class="special">};</span>
1786 And, the source file (see <a href="../../../example/features/no_lambdas.cpp" target="_top"><code class="literal">no_lambdas.cpp</code></a>):
1790 <pre class="programlisting"><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">iarray</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">max</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">count</span><span class="special">)</span> <span class="special">:</span>
1791 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">iarray</span><span class="special">>(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span>
1792 <span class="special">&</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special">,</span> <span class="identifier">max</span><span class="special">,</span> <span class="identifier">count</span><span class="special">)),</span>
1793 <span class="identifier">values_</span><span class="special">(</span><span class="keyword">new</span> <span class="keyword">int</span><span class="special">[</span><span class="identifier">max</span><span class="special">]),</span> <span class="comment">// Member initializations can be here.</span>
1794 <span class="identifier">capacity_</span><span class="special">(</span><span class="identifier">max</span><span class="special">)</span>
1795 <span class="special">{</span>
1796 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_instances</span><span class="special">;</span>
1797 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
1798 <span class="special">.</span><span class="identifier">old</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">constructor_old</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">old_instances</span><span class="special">)))</span>
1799 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span>
1800 <span class="special">&</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">constructor_postcondition</span><span class="special">,</span>
1801 <span class="keyword">this</span><span class="special">,</span>
1802 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">max</span><span class="special">),</span>
1803 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">count</span><span class="special">),</span>
1804 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">old_instances</span><span class="special">)</span>
1805 <span class="special">))</span>
1806 <span class="special">;</span>
1808 <span class="keyword">for</span><span class="special">(</span><span class="keyword">unsigned</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="identifier">count</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">i</span><span class="special">]</span> <span class="special">=</span> <span class="keyword">int</span><span class="special">();</span>
1809 <span class="identifier">size_</span> <span class="special">=</span> <span class="identifier">count</span><span class="special">;</span>
1810 <span class="special">++</span><span class="identifier">instances_</span><span class="special">;</span>
1811 <span class="special">}</span>
1813 <span class="identifier">iarray</span><span class="special">::~</span><span class="identifier">iarray</span><span class="special">()</span> <span class="special">{</span>
1814 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_instances</span><span class="special">;</span>
1815 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">destructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
1816 <span class="special">.</span><span class="identifier">old</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">destructor_old</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span>
1817 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">old_instances</span><span class="special">)))</span>
1818 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">destructor_postcondition</span><span class="special">,</span>
1819 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">old_instances</span><span class="special">)))</span>
1820 <span class="special">;</span>
1822 <span class="keyword">delete</span><span class="special">[]</span> <span class="identifier">values_</span><span class="special">;</span>
1823 <span class="special">--</span><span class="identifier">instances_</span><span class="special">;</span>
1824 <span class="special">}</span>
1826 <span class="keyword">void</span> <span class="identifier">iarray</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">value</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span><span class="special">)</span> <span class="special">{</span>
1827 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">></span> <span class="identifier">old_size</span><span class="special">;</span>
1828 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="keyword">this</span><span class="special">)</span>
1829 <span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">push_back_precondition</span><span class="special">,</span> <span class="keyword">this</span><span class="special">))</span>
1830 <span class="special">.</span><span class="identifier">old</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">push_back_old</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">v</span><span class="special">),</span>
1831 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">old_size</span><span class="special">)))</span>
1832 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">push_back_postcondition</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span>
1833 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">old_size</span><span class="special">)))</span>
1834 <span class="special">;</span>
1836 <span class="identifier">values_</span><span class="special">[</span><span class="identifier">size_</span><span class="special">++]</span> <span class="special">=</span> <span class="identifier">value</span><span class="special">;</span>
1837 <span class="special">}</span>
1839 <span class="keyword">unsigned</span> <span class="identifier">iarray</span><span class="special">::</span><span class="identifier">capacity</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
1840 <span class="comment">// Check invariants.</span>
1841 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
1842 <span class="keyword">return</span> <span class="identifier">capacity_</span><span class="special">;</span>
1843 <span class="special">}</span>
1845 <span class="keyword">unsigned</span> <span class="identifier">iarray</span><span class="special">::</span><span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
1846 <span class="comment">// Check invariants.</span>
1847 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
1848 <span class="keyword">return</span> <span class="identifier">size_</span><span class="special">;</span>
1849 <span class="special">}</span>
1851 <span class="keyword">int</span> <span class="identifier">iarray</span><span class="special">::</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">{</span>
1852 <span class="comment">// Check static invariants.</span>
1853 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span><span class="identifier">iarray</span><span class="special">>();</span>
1854 <span class="keyword">return</span> <span class="identifier">instances_</span><span class="special">;</span>
1855 <span class="special">}</span>
1857 <span class="keyword">int</span> <span class="identifier">iarray</span><span class="special">::</span><span class="identifier">instances_</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
1862 If programmers also want to fully enforce all contract programming constant-correctness
1863 requirements at compile-time, they should follow these rules when programming
1864 the contract functions (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>):
1866 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1867 <li class="listitem">
1868 Precondition functions (i.e., the <code class="computeroutput"><span class="special">...</span><span class="identifier">_precondition</span></code> functions in the example
1869 above) can take their arguments either by <code class="computeroutput"><span class="keyword">const</span></code>
1870 value or by <code class="computeroutput"><span class="keyword">const</span><span class="special">&</span></code>,
1871 and when they are member functions they should be either <code class="computeroutput"><span class="keyword">static</span></code> or <code class="computeroutput"><span class="keyword">const</span></code>
1874 <li class="listitem">
1875 Postcondition functions (i.e., the <code class="computeroutput"><span class="special">...</span><span class="identifier">_postcondition</span></code> functions in the example
1876 above) should take their arguments by <code class="computeroutput"><span class="keyword">const</span><span class="special">&</span></code>, and when they are member functions
1877 they should be either <code class="computeroutput"><span class="keyword">static</span></code>
1878 or <code class="computeroutput"><span class="keyword">const</span></code> functions.
1880 <li class="listitem">
1881 Similarly, exception guarantee functions (not shown in the example above)
1882 should take their arguments by <code class="computeroutput"><span class="keyword">const</span><span class="special">&</span></code>, and when they are member functions
1883 they should be either <code class="computeroutput"><span class="keyword">static</span></code>
1884 or <code class="computeroutput"><span class="keyword">const</span></code> functions.
1886 <li class="listitem">
1887 Old value functions (i.e., the <code class="computeroutput"><span class="special">...</span><span class="identifier">_old</span></code> functions in the example above)
1888 should take their arguments by <code class="computeroutput"><span class="keyword">const</span><span class="special">&</span></code> a part from old value pointers that
1889 should be taken by <code class="computeroutput"><span class="special">&</span></code>
1890 (so only old value pointers can be modified), and when they are member
1891 functions they should be either <code class="computeroutput"><span class="keyword">static</span></code>
1892 or <code class="computeroutput"><span class="keyword">const</span></code> functions.
1894 <li class="listitem">
1895 For constructors: Precondition, old value, and exception guarantee functions
1896 should be <code class="computeroutput"><span class="keyword">static</span></code> (because
1897 there is no valid object <code class="computeroutput"><span class="keyword">this</span></code>
1898 if the constructor body does not run successfully, see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constructor_calls" title="Constructor Calls">Constructor
1901 <li class="listitem">
1902 For destructors: Postcondition functions should be <code class="computeroutput"><span class="keyword">static</span></code>
1903 (because there is no valid object <code class="computeroutput"><span class="keyword">this</span></code>
1904 after the destructor body runs successfully, but exception guarantee
1905 functions do not have to be <code class="computeroutput"><span class="keyword">static</span></code>
1906 since the object <code class="computeroutput"><span class="keyword">this</span></code> is
1907 still valid because the destructor body did not run successfully, see
1908 <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.destructor_calls" title="Destructor Calls">Destructor
1913 Note that the extra contract functions also allow to keep the contract code
1914 in the header file while all function bodies are implemented in a separate
1915 source file (including the constructor member initialization list, that could
1916 not be done with the techniques shown in <a class="link" href="extras.html#boost_contract.extras.separate_body_implementation" title="Separate Body Implementation">Separate
1917 Body Implementation</a>). <a href="#ftn.boost_contract.extras.no_lambda_functions__no_c__11_.f2" class="footnote" name="boost_contract.extras.no_lambda_functions__no_c__11_.f2"><sup class="footnote">[80]</sup></a> Also note that the contract functions can always be declared
1918 <code class="computeroutput"><span class="keyword">private</span></code> if programmers need
1919 to exactly control the public members of the class (this was not done in
1920 this example only for brevity).
1923 The authors think this library is most useful when used together with C++11
1924 lambda functions (because of the large amount of boiler-plate code required
1925 when C++11 lambdas are not used as also shown by the example above).
1928 <div class="section">
1929 <div class="titlepage"><div><div><h3 class="title">
1930 <a name="boost_contract.extras.no_macros__and_no_variadic_macros_"></a><a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
1931 Macros (and No Variadic Macros)</a>
1932 </h3></div></div></div>
1934 It is possible to specify contracts without using most of the macros provided
1935 by this library and programming the related code manually instead (the only
1936 macros that cannot be programmed manually are <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>,
1937 <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDES.html" title="Macro BOOST_CONTRACT_OVERRIDES">BOOST_CONTRACT_OVERRIDES</a></code>,
1938 and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394998912688.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>).
1940 <div class="note"><table border="0" summary="Note">
1942 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
1943 <th align="left">Note</th>
1945 <tr><td align="left" valign="top"><p>
1946 Some of this library macros are variadic macros, others are not (see below).
1947 Variadic macros were officially added to the language in C++11 but most
1948 compilers have been supporting them as an extension for a long time, plus
1949 all compilers that support C++11 lambda functions should also support C++11
1950 variadic macros (and this library might rarely be used without the convenience
1951 of C++11 lambda functions, see <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
1952 Lambda Functions</a>). <a href="#ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f0" class="footnote" name="boost_contract.extras.no_macros__and_no_variadic_macros_.f0"><sup class="footnote">[81]</sup></a> Therefore, the rest of this section can be considered mainly
1953 a curiosity because programmers should seldom, if ever, need to use this
1954 library without using its macros.
1958 <a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h0"></a>
1959 <span class="phrase"><a name="boost_contract.extras.no_macros__and_no_variadic_macros_.overrides"></a></span><a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_.overrides">Overrides</a>
1962 As shown in <a class="link" href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public
1963 Function Overrides</a> and <a class="link" href="advanced.html#boost_contract.advanced.named_overrides" title="Named Overrides">Named
1964 Overrides</a>, this library provides the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>
1965 and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45394998912688.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>
1966 macros to program contracts for overriding public functions (see <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_MAX_ARGS.html" title="Macro BOOST_CONTRACT_MAX_ARGS">BOOST_CONTRACT_MAX_ARGS</a></code> for compilers
1967 that do not support variadic templates). <a href="#ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f1" class="footnote" name="boost_contract.extras.no_macros__and_no_variadic_macros_.f1"><sup class="footnote">[82]</sup></a> These macro cannot be programmed manually but they are not variadic
1968 macros (so programmers should be able to use them on any C++ compiler with
1969 a sound support for SFINAE). <a href="#ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f2" class="footnote" name="boost_contract.extras.no_macros__and_no_variadic_macros_.f2"><sup class="footnote">[83]</sup></a> The <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDES.html" title="Macro BOOST_CONTRACT_OVERRIDES">BOOST_CONTRACT_OVERRIDES</a></code>
1970 macro is a variadic macro instead but programmes can manually repeat the
1971 non-variadic macro <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>
1972 for each overriding public function name on compilers that do not support
1976 <a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h1"></a>
1977 <span class="phrase"><a name="boost_contract.extras.no_macros__and_no_variadic_macros_.assertions__not_variadic_"></a></span><a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_.assertions__not_variadic_">Assertions
1981 As shown in <a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a>,
1982 <a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>,
1983 <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception Guarantees</a>,
1984 <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class Invariants</a>,
1985 etc. this library provides the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
1986 macro to assert contract conditions. This is not a variadic macro and programmers
1987 should be able to use it on all C++ compilers. In any case, the invocation
1988 <code class="computeroutput"><span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>cond</em></span></code><code class="computeroutput"><span class="special">)</span></code> simply expands to code equivalent to the
1989 following: <a href="#ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f3" class="footnote" name="boost_contract.extras.no_macros__and_no_variadic_macros_.f3"><sup class="footnote">[84]</sup></a>
1991 <pre class="programlisting"><span class="keyword">if</span><span class="special">(!(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">))</span> <span class="special">{</span>
1992 <span class="keyword">throw</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">assertion_failure</span><span class="special">(</span><span class="identifier">__FILE__</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">,</span>
1993 <span class="identifier">BOOST_PP_STRINGIZE</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">));</span>
1994 <span class="special">}</span>
1997 In fact, this library considers any exception thrown from within preconditions,
1998 postconditions, exception guarantees, and class invariants as a contract
1999 failure and reports it calling the related contract failure handler (<code class="computeroutput"><a class="link" href="../boost/contract/precondition_failure.html" title="Function precondition_failure">boost::contract::precondition_failure</a></code>,
2000 etc.). If there is a need for it, programmers can always program contract
2001 assertions that throw specific user-defined exceptions as follow (see <a class="link" href="advanced.html#boost_contract.advanced.throw_on_failures__and__noexcept__" title="Throw on Failures (and noexcept)">Throw
2004 <pre class="programlisting"><span class="keyword">if</span><span class="special">(!</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span> <span class="keyword">throw</span> <code class="literal"><span class="emphasis"><em>exception-object</em></span></code><span class="special">;</span>
2007 However, using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
2008 is convenient because it always allows this library to show an informative
2009 message in case of assertion failure containing the assertion code, file
2010 name, line number, etc.
2013 As shown in <a class="link" href="extras.html#boost_contract.extras.assertion_levels" title="Assertion Levels">Assertion
2014 Levels</a>, this library pre-defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45395000817520.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
2015 and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45395027441616.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
2016 assertion levels. These macros are not variadic macros and programmers should
2017 be able to use them on all C++ compilers. In any case, their implementations
2018 are equivalent to the following:
2020 <pre class="programlisting"><span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_CONTRACT_AUDITS</span>
2021 <span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTRACT_ASSERT_AUDIT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span> <span class="special">\</span>
2022 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span>
2023 <span class="preprocessor">#else</span>
2024 <span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTRACT_ASSERT_AUDIT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span> <span class="special">\</span>
2025 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="keyword">true</span> <span class="special">||</span> <span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">))</span>
2026 <span class="preprocessor">#endif</span>
2028 <span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTRACT_ASSERT_AXIOM</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span> <span class="special">\</span>
2029 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="keyword">true</span> <span class="special">||</span> <span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">))</span>
2032 <a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h2"></a>
2033 <span class="phrase"><a name="boost_contract.extras.no_macros__and_no_variadic_macros_.base_types__variadic_"></a></span><a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_.base_types__variadic_">Base
2034 Types (Variadic)</a>
2037 As shown in <a class="link" href="tutorial.html#boost_contract.tutorial.base_classes__subcontracting_" title="Base Classes (Subcontracting)">Base
2038 Classes</a>, this library provides the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
2039 variadic macro to declare the <code class="computeroutput"><span class="identifier">base_types</span></code>
2040 member type that will expand to the list of all public bases for a derived
2041 class. Programmers can also declare <code class="computeroutput"><span class="identifier">base_types</span></code>
2042 without using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
2043 at the cost of writing a bit more code and increase maintenance efforts.
2044 For example (see <a href="../../../example/features/base_types_no_macro.cpp" target="_top"><code class="literal">base_types_no_macro.cpp</code></a>):
2048 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mpl</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
2050 <span class="keyword">class</span> <span class="identifier">chars</span> <span class="special">:</span>
2051 <span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">chars</span><span class="special">>,</span>
2052 <span class="keyword">public</span> <span class="identifier">unique_chars</span><span class="special">,</span>
2053 <span class="keyword">public</span> <span class="keyword">virtual</span> <span class="identifier">pushable</span><span class="special"><</span><span class="keyword">char</span><span class="special">>,</span>
2054 <span class="keyword">virtual</span> <span class="keyword">protected</span> <span class="identifier">has_size</span><span class="special">,</span>
2055 <span class="keyword">private</span> <span class="identifier">has_empty</span>
2056 <span class="special">{</span>
2057 <span class="keyword">public</span><span class="special">:</span>
2058 <span class="comment">// Program `base_types` without macros (list only public bases).</span>
2059 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">unique_chars</span><span class="special">,</span> <span class="identifier">pushable</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="special">></span> <span class="identifier">base_types</span><span class="special">;</span>
2061 <span class="comment">/* ... */</span>
2066 The <code class="computeroutput"><span class="identifier">base_types</span></code> member type
2067 must be a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span></code>
2068 which must list <span class="emphasis"><em>all and only</em></span> <code class="computeroutput"><span class="keyword">public</span></code>
2069 base classes (because only public bases subcontract, see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.function_calls" title="Function Calls">Function
2070 Calls</a>), and in the same order these public base classes appear in
2071 the derived class inheritance list. If the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
2072 macro is not used, it is the responsibility of the programmers to maintain
2073 the correct list of bases in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span></code> each time the derived class inheritance
2074 list changes (this might significantly complicate maintenance).
2077 In general, it is recommended to use the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
2078 macro whenever possible.
2081 <a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h3"></a>
2082 <span class="phrase"><a name="boost_contract.extras.no_macros__and_no_variadic_macros_.old_values__variadic_"></a></span><a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_.old_values__variadic_">Old
2083 Values (Variadic)</a>
2086 As shown in <a class="link" href="tutorial.html#boost_contract.tutorial.old_values" title="Old Values">Old Values</a>,
2087 this library provides the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
2088 variadic macro to assign old value copies. Programmers can also assign old
2089 values without using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
2090 at the cost of writing a bit more code manually. For example (see <a href="../../../example/features/old_no_macro.cpp" target="_top"><code class="literal">old_no_macro.cpp</code></a>):
2094 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
2095 <span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
2096 <span class="keyword">public</span><span class="special">:</span>
2097 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span>
2098 <span class="comment">// Program old value instead of using `OLD(size())` macro.</span>
2099 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">></span> <span class="identifier">old_size</span> <span class="special">=</span>
2100 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">make_old</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">copy_old</span><span class="special">(</span><span class="identifier">v</span><span class="special">)</span> <span class="special">?</span>
2101 <span class="identifier">size</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">null_old</span><span class="special">())</span>
2102 <span class="special">;</span>
2104 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="keyword">this</span><span class="special">)</span>
2105 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
2106 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
2107 <span class="special">})</span>
2108 <span class="special">;</span>
2110 <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">value</span><span class="special">);</span>
2111 <span class="special">}</span>
2113 <span class="comment">/* ... */</span>
2118 The ternary operator <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">copy_old</span><span class="special">(</span><span class="identifier">v</span><span class="special">)</span>
2119 <span class="special">?</span> <span class="identifier">size</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">null_old</span><span class="special">()</span></code> must be used here to avoid evaluating and
2120 copying the old value expression <code class="computeroutput"><span class="identifier">size</span><span class="special">()</span></code> when <code class="computeroutput"><a class="link" href="../boost/contract/copy_old_idm45394998944672.html" title="Function copy_old">boost::contract::copy_old</a></code>
2121 returns <code class="computeroutput"><span class="keyword">false</span></code> (because old values
2122 are not being copied when postcondition and exception guarantee checking
2123 is disabled at run-time, an overridden virtual function call is not checking
2124 postconditions or exception guarantees yet, etc.). The enclosing <code class="computeroutput"><a class="link" href="../boost/contract/make_old_idm45394998968720.html" title="Function make_old">boost::contract::make_old</a></code>
2125 copies the old value expression and creates an old value pointer. Otherwise,
2126 <code class="computeroutput"><a class="link" href="../boost/contract/null_old.html" title="Function null_old">boost::contract::null_old</a></code>
2127 indicates that a null old value pointer should be created.
2130 The <code class="computeroutput"><a class="link" href="../boost/contract/make_old_idm45394998968720.html" title="Function make_old">boost::contract::make_old</a></code>
2131 and <code class="computeroutput"><a class="link" href="../boost/contract/copy_old_idm45394998944672.html" title="Function copy_old">boost::contract::copy_old</a></code>
2132 functions are used exactly as shown above but without the extra <code class="computeroutput"><span class="identifier">v</span></code> parameter when they are called from within
2133 non-virtual functions (see <a class="link" href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public
2134 Function Overrides</a>). The old value pointer returned by <code class="computeroutput"><a class="link" href="../boost/contract/make_old_idm45394998968720.html" title="Function make_old">boost::contract::make_old</a></code>
2135 can be assigned to either <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code>
2136 or <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>
2137 (see <a class="link" href="extras.html#boost_contract.extras.old_value_requirements__templates_" title="Old Value Requirements (Templates)">Old
2138 Value Requirements</a>).
2141 In general, it is recommended to use the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
2142 macro whenever possible.
2145 <a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h4"></a>
2146 <span class="phrase"><a name="boost_contract.extras.no_macros__and_no_variadic_macros_.macro_interface__variadic_"></a></span><a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_.macro_interface__variadic_">Macro
2147 Interface (Variadic)</a>
2150 Almost all macros defined in <code class="computeroutput"><a class="link" href="../reference.html#header.boost.contract_macro_hpp" title="Header <boost/contract_macro.hpp>">boost/contract_macro.hpp</a></code>
2151 are variadic macros. On compilers that do not support variadic macros, programmers
2152 can manually disable contract code compilation using <code class="computeroutput"><span class="preprocessor">#ifndef</span>
2153 <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
2154 statements as shown in <a class="link" href="extras.html#boost_contract.extras.disable_contract_compilation__macro_interface_" title="Disable Contract Compilation (Macro Interface)">Disable
2155 Contract Compilation</a>.
2158 <div class="footnotes">
2159 <br><hr style="width:100; text-align:left;margin-left: 0">
2160 <div id="ftn.boost_contract.extras.old_value_requirements__templates_.f0" class="footnote">
2161 <p><a href="#boost_contract.extras.old_value_requirements__templates_.f0" class="para"><sup class="para">[68] </sup></a>
2162 <span class="bold"><strong>Rationale:</strong></span> <a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
2163 and other proposals to add contracts to C++ do not provide a mechanism
2164 to selectively disable copies only for old value types that are not copy
2165 constructible. However, this library provides such a mechanism to allow
2166 to program contracts for template code without necessarily adding extra
2167 copy constructible type requirements that would not be present if it were
2168 not for copying old values (so compiling the code with and without contracts
2169 will not necessarily alter the type requirements of the program). Something
2170 similar could be achieved combing C++17 <code class="computeroutput"><span class="keyword">if</span>
2171 <span class="keyword">constexpr</span></code> with <a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
2172 or <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a> so that old value expressions
2173 within template code can be guarded by <code class="computeroutput"><span class="keyword">if</span>
2174 <span class="keyword">constexpr</span></code> statements checking if
2175 the old value types are copyable or not. For example, assuming old values
2176 are added to <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a> (using some kind
2177 of <code class="computeroutput"><span class="identifier">oldof</span><span class="special">(...)</span></code>
2178 syntax) and that C++17 <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code> can be used within <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a>
2181 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
2182 <span class="keyword">void</span> <span class="identifier">offset</span><span class="special">(</span><span class="identifier">T</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">count</span><span class="special">)</span>
2183 <span class="special">[[</span><span class="identifier">ensures</span><span class="special">:</span> <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_copy_constructible</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">)</span> <span class="identifier">x</span> <span class="special">==</span> <span class="identifier">oldof</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">count</span><span class="special">]]</span>
2184 <span class="special">...</span>
2189 <div id="ftn.boost_contract.extras.old_value_requirements__templates_.f1" class="footnote">
2190 <p><a href="#boost_contract.extras.old_value_requirements__templates_.f1" class="para"><sup class="para">[69] </sup></a>
2191 Technically, on C++17 it is possible to use <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code>
2192 together with <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
2193 instead of using <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>,
2196 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
2197 <span class="keyword">void</span> <span class="identifier">offset</span><span class="special">(</span><span class="identifier">T</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">count</span><span class="special">)</span> <span class="special">{</span>
2198 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">old_x</span><span class="special">;</span>
2199 <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">is_old_value_copyable</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">)</span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
2200 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
2201 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
2202 <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">is_old_value_copyable</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span> <span class="special">+</span> <span class="identifier">count</span><span class="special">);</span>
2203 <span class="special">})</span>
2204 <span class="special">;</span>
2206 <span class="identifier">x</span> <span class="special">+=</span> <span class="identifier">count</span><span class="special">;</span>
2207 <span class="special">}</span>
2210 However, the authors find this code less readable and more verbose than
2211 its equivalent that uses <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>.
2212 Guarding old value copies and related assertions with <code class="computeroutput"><span class="keyword">if</span>
2213 <span class="keyword">constexpr</span></code> is useful instead when
2214 the guard condition checks type requirements more complex than just <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code>
2215 (as shown later in this documentation).
2218 <div id="ftn.boost_contract.extras.assertion_requirements__templates_.f0" class="footnote">
2219 <p><a href="#boost_contract.extras.assertion_requirements__templates_.f0" class="para"><sup class="para">[70] </sup></a>
2220 <span class="bold"><strong>Rationale:</strong></span> <a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
2221 and other proposals to add contracts to C++ do not provide a mechanism
2222 to selectively disable assertions based on their type requirements. However,
2223 this library provides such a mechanism to allow to program contracts for
2224 template code without necessarily adding extra type requirements that would
2225 not be present if it was not for the contracts (so compiling the code with
2226 and without contracts will not alter the type requirements of the program).
2227 Something similar could be achieved combing C++17 <code class="computeroutput"><span class="keyword">if</span>
2228 <span class="keyword">constexpr</span></code> with <a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
2229 or <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a> so that contract assertions
2230 within template code could be guarded by <code class="computeroutput"><span class="keyword">if</span>
2231 <span class="keyword">constexpr</span></code> statements checking the
2232 related type requirements (<a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
2233 already allows of <code class="computeroutput"><span class="keyword">if</span></code> statements
2234 in contracts under the name of <span class="emphasis"><em>select assertions</em></span>,
2235 <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a> does not so probably <code class="computeroutput"><span class="keyword">if</span></code> statements should be added to <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a>
2236 as well). For example, assuming C++17 <code class="computeroutput"><span class="keyword">if</span>
2237 <span class="keyword">constexpr</span></code> can be used within <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a> contracts:
2239 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
2240 <span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
2241 <span class="keyword">public</span><span class="special">:</span>
2242 <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">)</span>
2243 <span class="special">[[</span><span class="identifier">ensures</span><span class="special">:</span> <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">)</span> <span class="identifier">back</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">value</span><span class="special">]]</span>
2244 <span class="special">...</span>
2245 <span class="special">};</span>
2250 <div id="ftn.boost_contract.extras.assertion_requirements__templates_.f1" class="footnote"><p><a href="#boost_contract.extras.assertion_requirements__templates_.f1" class="para"><sup class="para">[71] </sup></a>
2251 The internal implementation of <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
2252 is optimized and it does not actually use <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>.
2254 <div id="ftn.boost_contract.extras.assertion_requirements__templates_.f2" class="footnote">
2255 <p><a href="#boost_contract.extras.assertion_requirements__templates_.f2" class="para"><sup class="para">[72] </sup></a>
2258 A part from its use within contracts, <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>
2259 can be used together with C++14 generic lambdas to emulate C++17 <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
2260 (<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">if_</span></code> and probably other approaches can
2261 also be used together with generic lambdas to emulate C++17 <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
2262 on C++14 compilers). For example, the following implementation of <code class="computeroutput"><span class="identifier">myadvance</span></code> will compile since C++14
2263 and it is more concise, easier to read and maintain than the usual implementation
2264 of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">advance</span></code> that uses tag dispatching (see
2265 <a href="../../../example/features/call_if_cxx14.cpp" target="_top"><code class="literal">call_if_cxx14.cpp</code></a>):
2271 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Dist</span><span class="special">></span>
2272 <span class="keyword">void</span> <span class="identifier">myadvance</span><span class="special">(</span><span class="identifier">Iter</span><span class="special">&</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">Dist</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span>
2273 <span class="identifier">Iter</span><span class="special">*</span> <span class="identifier">p</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">i</span><span class="special">;</span> <span class="comment">// So captures change actual pointed iterator value.</span>
2274 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">call_if</span><span class="special"><</span><span class="identifier">is_random_access_iterator</span><span class="special"><</span><span class="identifier">Iter</span><span class="special">></span> <span class="special">>(</span>
2275 <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">([]</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">auto</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// C++14 generic lambda.</span>
2276 <span class="special">*</span><span class="identifier">p</span> <span class="special">+=</span> <span class="identifier">n</span><span class="special">;</span>
2277 <span class="special">},</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span>
2278 <span class="special">).</span><span class="keyword">template</span> <span class="identifier">else_if</span><span class="special"><</span><span class="identifier">is_bidirectional_iterator</span><span class="special"><</span><span class="identifier">Iter</span><span class="special">></span> <span class="special">>(</span>
2279 <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">([]</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">auto</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span>
2280 <span class="keyword">if</span><span class="special">(</span><span class="identifier">n</span> <span class="special">>=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">while</span><span class="special">(</span><span class="identifier">n</span><span class="special">--)</span> <span class="special">++*</span><span class="identifier">p</span><span class="special">;</span>
2281 <span class="keyword">else</span> <span class="keyword">while</span><span class="special">(</span><span class="identifier">n</span><span class="special">++)</span> <span class="special">--*</span><span class="identifier">p</span><span class="special">;</span>
2282 <span class="special">},</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span>
2283 <span class="special">).</span><span class="keyword">template</span> <span class="identifier">else_if</span><span class="special"><</span><span class="identifier">is_input_iterator</span><span class="special"><</span><span class="identifier">Iter</span><span class="special">></span> <span class="special">>(</span>
2284 <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">([]</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">auto</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span>
2285 <span class="keyword">while</span><span class="special">(</span><span class="identifier">n</span><span class="special">--)</span> <span class="special">++*</span><span class="identifier">p</span><span class="special">;</span>
2286 <span class="special">},</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span>
2287 <span class="special">).</span><span class="identifier">else_</span><span class="special">(</span>
2288 <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">([]</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">false_</span><span class="special">)</span> <span class="special">{</span>
2289 <span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">false_</span><span class="special">,</span> <span class="string">"requires at least input iterator"</span><span class="special">);</span>
2290 <span class="special">},</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">false_type</span><span class="special">())</span> <span class="comment">// Use constexpr value.</span>
2291 <span class="special">);</span>
2292 <span class="special">}</span>
2299 Of course, since C++17 the implementation that uses <code class="computeroutput"><span class="keyword">if</span>
2300 <span class="keyword">constexpr</span></code> is even more readable
2303 <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Dist</span><span class="special">></span>
2304 <span class="keyword">void</span> <span class="identifier">myadvance</span><span class="special">(</span><span class="identifier">Iter</span><span class="special">&</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">Dist</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span>
2305 <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">is_random_access_iterator</span><span class="special"><</span><span class="identifier">Iter</span><span class="special">>::</span><span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
2306 <span class="identifier">i</span> <span class="special">+=</span> <span class="identifier">n</span><span class="special">;</span>
2307 <span class="special">}</span> <span class="keyword">else</span> <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">is_bidirectional_iterator</span><span class="special"><</span><span class="identifier">Iter</span><span class="special">>::</span><span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
2308 <span class="keyword">if</span><span class="special">(</span><span class="identifier">n</span> <span class="special">>=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">while</span><span class="special">(</span><span class="identifier">n</span><span class="special">--)</span> <span class="special">++</span><span class="identifier">i</span><span class="special">;</span>
2309 <span class="keyword">else</span> <span class="keyword">while</span><span class="special">(</span><span class="identifier">n</span><span class="special">++)</span> <span class="special">--</span><span class="identifier">i</span><span class="special">;</span>
2310 <span class="special">}</span> <span class="keyword">else</span> <span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">is_input_iterator</span><span class="special"><</span><span class="identifier">Iter</span><span class="special">>::</span><span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
2311 <span class="keyword">while</span><span class="special">(</span><span class="identifier">n</span><span class="special">--)</span> <span class="special">++</span><span class="identifier">i</span><span class="special">;</span>
2312 <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
2313 <span class="keyword">static_assert</span><span class="special">(</span><span class="keyword">false</span><span class="special">,</span> <span class="string">"requires at least input iterator"</span><span class="special">);</span>
2314 <span class="special">}</span>
2315 <span class="special">}</span>
2322 <div id="ftn.boost_contract.extras.volatile_public_functions.f0" class="footnote"><p><a href="#boost_contract.extras.volatile_public_functions.f0" class="para"><sup class="para">[73] </sup></a>
2323 <span class="bold"><strong>Rationale:</strong></span> Constructors and destructors
2324 check <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
2325 and <code class="computeroutput"><span class="keyword">const</span></code> invariants in that
2326 order because the qualifier that can be applied to more calls is checked
2327 first (note that <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
2328 calls can be made on any object while <code class="computeroutput"><span class="keyword">const</span></code>
2329 calls cannot be made on <code class="computeroutput"><span class="keyword">volatile</span></code>
2330 objects, in that sense the <code class="computeroutput"><span class="keyword">const</span>
2331 <span class="keyword">volatile</span></code> qualifier can be applied
2332 to more calls than <code class="computeroutput"><span class="keyword">const</span></code> alone
2333 can). This is consistent with <code class="computeroutput"><span class="keyword">static</span></code>
2334 class invariants that are checked even before <code class="computeroutput"><span class="keyword">const</span>
2335 <span class="keyword">volatile</span></code> invariants (the <code class="computeroutput"><span class="keyword">static</span></code> classifier can be applied to even
2336 more calls than <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>,
2337 in fact an object is not even needed to make static calls).
2339 <div id="ftn.boost_contract.extras.volatile_public_functions.f1" class="footnote"><p><a href="#boost_contract.extras.volatile_public_functions.f1" class="para"><sup class="para">[74] </sup></a>
2340 <span class="bold"><strong>Rationale:</strong></span> Note that while all public
2341 functions can be made to check <code class="computeroutput"><span class="keyword">const</span>
2342 <span class="keyword">volatile</span></code> invariants, it is never
2343 possible to make volatile public functions check <code class="computeroutput"><span class="keyword">const</span></code>
2344 non-volatile invariants. That is because both <code class="computeroutput"><span class="keyword">const</span></code>
2345 and <code class="computeroutput"><span class="keyword">volatile</span></code> can always be
2346 added but never stripped in C++ (a part from forcefully via <code class="computeroutput"><span class="keyword">const_cast</span></code>) but <code class="computeroutput"><span class="keyword">const</span></code>
2347 is always automatically added by this library in order to enforce contract
2348 constant-correctness (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
2349 That said, it would be too stringent for this library to also automatically
2350 add <code class="computeroutput"><span class="keyword">volatile</span></code> and require all
2351 functions to check <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code> (not just <code class="computeroutput"><span class="keyword">const</span></code>)
2352 invariants because only <code class="computeroutput"><span class="keyword">volatile</span></code>
2353 members can be accessed from <code class="computeroutput"><span class="keyword">const</span>
2354 <span class="keyword">volatile</span></code> invariants so there could
2355 be many <code class="computeroutput"><span class="keyword">const</span></code> (but not <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>)
2356 members that are accessible from <code class="computeroutput"><span class="keyword">const</span></code>
2357 invariants but not from <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code> invariants. To avoid this confusion,
2358 this library has chosen to draw a clear dichotomy between <code class="computeroutput"><span class="keyword">const</span></code> and <code class="computeroutput"><span class="keyword">const</span>
2359 <span class="keyword">volatile</span></code> invariants so that only
2360 volatile public functions check <code class="computeroutput"><span class="keyword">const</span>
2361 <span class="keyword">volatile</span></code> invariants and only non-volatile
2362 public functions check <code class="computeroutput"><span class="keyword">const</span></code>
2363 (but not <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>)
2364 invariants. This is a clear distinction and it should serve most cases.
2365 If programmers need non-volatile public functions to also check <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
2366 invariants, they can explicitly do so by calling the <code class="computeroutput"><span class="keyword">const</span>
2367 <span class="keyword">volatile</span></code> invariant function from
2368 the <code class="computeroutput"><span class="keyword">const</span></code> invariant function
2369 as shown in this documentation.
2371 <div id="ftn.boost_contract.extras.move_operations.f0" class="footnote"><p><a href="#boost_contract.extras.move_operations.f0" class="para"><sup class="para">[75] </sup></a>
2372 In this example, the <code class="computeroutput"><span class="identifier">moved</span><span class="special">()</span></code> function is simple enough that programmers
2373 could decide to not even call <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45394998885120.html" title="Function template public_function">boost::contract::public_function</a></code>
2374 from it for optimization reasons. However, calling <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45394998885120.html" title="Function template public_function">boost::contract::public_function</a></code>
2375 from <code class="computeroutput"><span class="identifier">moved</span><span class="special">()</span></code>
2376 has no negative impact, a part from run-time overhead, because this library
2377 automatically disables contract checking while checking other contracts
2378 (so this call will not cause infinite recursion).
2380 <div id="ftn.boost_contract.extras.assertion_levels.f0" class="footnote"><p><a href="#boost_contract.extras.assertion_levels.f0" class="para"><sup class="para">[76] </sup></a>
2381 The assertion levels predefined by this library are similar to the default,
2382 audit, and axiom levels from <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a>.
2384 <div id="ftn.boost_contract.extras.separate_body_implementation.f0" class="footnote">
2385 <p><a href="#boost_contract.extras.separate_body_implementation.f0" class="para"><sup class="para">[77] </sup></a>
2386 When used as default parameter values, lambda functions allow to program
2387 code statements within function declarations. However, these lambadas cannot
2388 be effectively used to program contracts in function declarations instead
2389 of definitions. That is because the C++11 standard does not allow lambdas
2390 in function declarations to capture any variable (for the good reason that
2391 it is not at all obvious how to correctly define the semantics of such
2392 captures). For example, the following code is not valid C++ and it does
2395 <pre class="programlisting"><span class="comment">// Specifications (in declaration).</span>
2396 <span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span>
2397 <span class="comment">// Error: Lambdas in default parameters cannot capture `this`, `x`, or any other variable.</span>
2398 <span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">void</span> <span class="special">()></span> <span class="identifier">pre</span> <span class="special">=</span> <span class="special">[&]</span> <span class="special">{</span>
2399 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">max</span><span class="special">());</span>
2400 <span class="special">},</span>
2401 <span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">void</span> <span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">const</span><span class="special">&)></span> <span class="identifier">post</span>
2402 <span class="special">=</span> <span class="special">[&]</span> <span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">result</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">old_x</span><span class="special">)</span>
2403 <span class="special">{</span>
2404 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
2405 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
2406 <span class="special">}</span>
2407 <span class="special">);</span>
2409 <span class="comment">// Implementation (in definition).</span>
2410 <span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span>
2411 <span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">void</span> <span class="special">()></span> <span class="identifier">pre</span><span class="special">,</span>
2412 <span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">void</span> <span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">const</span><span class="special">&)></span> <span class="identifier">post</span>
2413 <span class="special">)</span> <span class="special">{</span>
2414 <span class="keyword">int</span> <span class="identifier">result</span><span class="special">;</span>
2415 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
2416 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
2417 <span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span><span class="identifier">pre</span><span class="special">)</span>
2418 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><span class="identifier">post</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">result</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">old_x</span><span class="special">)))</span>
2419 <span class="special">;</span>
2421 <span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">++;</span> <span class="comment">// Function body.</span>
2422 <span class="special">}</span>
2425 In any case, even if the above code compiled, it would require significant
2426 boiler-plate code to bind return and old values.
2429 <div id="ftn.boost_contract.extras.no_lambda_functions__no_c__11_.f0" class="footnote"><p><a href="#boost_contract.extras.no_lambda_functions__no_c__11_.f0" class="para"><sup class="para">[78] </sup></a>
2430 Alternatively, on compilers that do not support C++11 lambda functions,
2431 <a href="http://www.boost.org/doc/libs/release/libs/local_function/doc/html/index.html" target="_top">Boost.LocalFunction</a>
2432 could be used to program the contract functors still within the function
2433 definitions (for example, see <a href="../../../example/features/no_lambdas_local_func.cpp" target="_top"><code class="literal">no_lambda_local_func.cpp</code></a>).
2434 In general, such a code is less verbose than the example shown in this
2435 section that uses contract functions programmed outside of the original
2436 function definitions (about 30% less lines of code) but the contract
2437 code is hard to read. Other libraries could also be used to program
2438 the contract functors without C++11 lambda functions (Boost.Lambda,
2439 Boost.Fusion, etc.) but again all these techniques will result in contract
2440 code either more verbose, or harder to read and maintain than the code
2441 that uses C++11 lambda functions.
2443 <div id="ftn.boost_contract.extras.no_lambda_functions__no_c__11_.f1" class="footnote"><p><a href="#boost_contract.extras.no_lambda_functions__no_c__11_.f1" class="para"><sup class="para">[79] </sup></a>
2444 If C++ allowed lambda functions to capture variables by constant reference
2445 (for example allowing a syntax like this <code class="computeroutput"><span class="special">[</span><span class="keyword">const</span><span class="special">&]</span>
2446 <span class="special">{</span> <span class="special">...</span>
2447 <span class="special">}</span></code> and <code class="computeroutput"><span class="special">[</span><span class="keyword">const</span><span class="special">&</span>
2448 </code><code class="literal"><span class="emphasis"><em>variable-name</em></span></code><code class="computeroutput"><span class="special">]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>,
2449 see <a href="https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/0UKQw9eo3N0" target="_top">https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/0UKQw9eo3N0</a>)
2450 also lambdas could be used to program contract functors that fully
2451 enforce <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>
2452 at compile-time. Note that C++11 lambdas allow to capture variables
2453 by value (using <code class="computeroutput"><span class="special">[=]</span> <span class="special">{</span>
2454 <span class="special">...</span> <span class="special">}</span></code>
2455 and <code class="computeroutput"><span class="special">[</span></code><code class="literal"><span class="emphasis"><em>variable-name</em></span></code><code class="computeroutput"><span class="special">]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>)
2456 and these value captures are <code class="computeroutput"><span class="keyword">const</span></code>
2457 (unless the lambda is explicitly declared <code class="computeroutput"><span class="keyword">mutable</span></code>)
2458 but they are not suitable to program postconditions and exception guarantees
2459 using this library (because those require capturing by reference, see
2460 <a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>
2461 and <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
2462 Guarantees</a>), plus they introduce a copy of the captured value
2463 that might be too expensive in general and therefore not suitable for
2464 preconditions either.
2466 <div id="ftn.boost_contract.extras.no_lambda_functions__no_c__11_.f2" class="footnote"><p><a href="#boost_contract.extras.no_lambda_functions__no_c__11_.f2" class="para"><sup class="para">[80] </sup></a>
2467 In this example, <code class="computeroutput"><span class="identifier">bind</span></code> was
2468 used to generate nullary functors from the contract functions. As always
2469 with <code class="computeroutput"><span class="identifier">bind</span></code>, <code class="computeroutput"><span class="identifier">cref</span></code> and <code class="computeroutput"><span class="identifier">ref</span></code>
2470 must be used to bind arguments by <code class="computeroutput"><span class="keyword">const</span><span class="special">&</span></code> and <code class="computeroutput"><span class="special">&</span></code>
2471 respectively, plus it might be necessary to explicitly <code class="computeroutput"><span class="keyword">static_cast</span></code>
2472 the function pointer passed to <code class="computeroutput"><span class="identifier">bind</span></code>
2473 for overloaded functions.
2475 <div id="ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f0" class="footnote"><p><a href="#boost_contract.extras.no_macros__and_no_variadic_macros_.f0" class="para"><sup class="para">[81] </sup></a>
2476 Compilation times of this library were measured to be comparable between
2477 compilers that support variadic macros and compilers that do not.
2479 <div id="ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f1" class="footnote"><p><a href="#boost_contract.extras.no_macros__and_no_variadic_macros_.f1" class="para"><sup class="para">[82] </sup></a>
2480 <span class="bold"><strong>Rationale:</strong></span> The <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_MAX_ARGS.html" title="Macro BOOST_CONTRACT_MAX_ARGS">BOOST_CONTRACT_MAX_ARGS</a></code>
2481 macro is named after <code class="computeroutput"><span class="identifier">BOOST_FUNCTION_MAX_ARGS</span></code>.
2483 <div id="ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f2" class="footnote"><p><a href="#boost_contract.extras.no_macros__and_no_variadic_macros_.f2" class="para"><sup class="para">[83] </sup></a>
2484 <span class="bold"><strong>Rationale:</strong></span> These macros expand to SFINAE-based
2485 introspection template code that are too complex to be programmed manually
2486 by users (that remains the case even if C++14 generic lambdas were to be
2487 used here). On a related note, in theory using C++14 generic lambdas, the
2488 <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>
2489 macro could be re-implemented in a way that can be expanded at function
2490 scope, instead of class scope (but there is not really a need to do that).
2492 <div id="ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f3" class="footnote"><p><a href="#boost_contract.extras.no_macros__and_no_variadic_macros_.f3" class="para"><sup class="para">[84] </sup></a>
2493 <span class="bold"><strong>Rationale:</strong></span> There is no need for the code
2494 expanded by <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
2495 to also use C++11 <code class="computeroutput"><span class="identifier">__func__</span></code>.
2496 That is because <code class="computeroutput"><span class="identifier">__func__</span></code>
2497 will always expand to the name <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> of the functor used to program the contract
2498 assertions (e.g., the internal name the compiler assigns to lambda functions)
2499 and it will not expand to the name of the actual function enclosing the
2500 contract declaration.
2504 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
2505 <td align="left"></td>
2506 <td align="right"><div class="copyright-footer">Copyright © 2008-2019 Lorenzo Caminiti<p>
2507 Distributed under the Boost Software License, Version 1.0 (see accompanying
2508 file LICENSE_1_0.txt or a copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
2513 <div class="spirit-nav">
2514 <a accesskey="p" href="advanced.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="examples.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>