boost/libs/contract/doc/html/boost_contract/extras.html
2022-12-15 23:45:23 +08:00

2467 lines
282 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Extras</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Contract 1.0.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Contract 1.0.0">
<link rel="prev" href="advanced.html" title="Advanced">
<link rel="next" href="examples.html" title="Examples">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="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>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_contract.extras"></a><a class="link" href="extras.html" title="Extras">Extras</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="extras.html#boost_contract.extras.old_value_requirements__templates_">Old
Value Requirements (Templates)</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.assertion_requirements__templates_">Assertion
Requirements (Templates)</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.volatile_public_functions">Volatile
Public Functions</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.move_operations">Move Operations</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.unions">Unions</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.assertion_levels">Assertion Levels</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.disable_contract_checking">Disable
Contract Checking</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.disable_contract_compilation__macro_interface_">Disable
Contract Compilation (Macro Interface)</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.separate_body_implementation">Separate
Body Implementation</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_">No
Lambda Functions (No C++11)</a></span></dt>
<dt><span class="section"><a href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_">No
Macros (and No Variadic Macros)</a></span></dt>
</dl></div>
<p>
This section can be consulted selectively for specific topics of interest.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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
Value Requirements (Templates)</a>
</h3></div></div></div>
<p>
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>
thus the type of that expression needs to be copyable. More precisely, dereferencing
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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code> to be <code class="computeroutput"><span class="keyword">true</span></code>,
otherwise this library will generate a compile-time error.
</p>
<p>
In some cases it might be acceptable, or even desirable, to cause a compile-time
error when a program uses old value types that are not copyable (because
it is not possible to fully check the correctness of the program as stated
by the contract assertions that use these old values). In these cases, programmers
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>
as seen so far.
</p>
<p>
However, in some other cases it might be desirable to simply skip assertions
that use old values when the respective old value types are not copyable,
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>
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>
and checking if the old value pointer is not null before dereferencing it
in postconditions. For example, consider the following function template
that could in general be instantiated for types <code class="computeroutput"><span class="identifier">T</span></code>
that are not copy constructible (that is for which <code class="computeroutput"><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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code> is <code class="computeroutput"><span class="keyword">false</span></code>,
see <a href="../../../example/features/old_if_copyable.cpp" target="_top"><code class="literal">old_if_copyable.cpp</code></a>):
<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>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="comment">// T might or might not be copyable.</span>
<span class="keyword">void</span> <span class="identifier">offset</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;</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>
<span class="comment">// No compiler error if T has no copy constructor...</span>
<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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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="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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="comment">// ...but old value null if T has no copy constructor.</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<span class="identifier">x</span> <span class="special">+=</span> <span class="identifier">count</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
The old value pointer <code class="computeroutput"><span class="identifier">old_x</span></code>
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>.
When <code class="computeroutput"><span class="identifier">T</span></code> is copyable, this
<code class="computeroutput"><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">]&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> behaves
like <code class="computeroutput"><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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>.
When <code class="computeroutput"><span class="identifier">T</span></code> is not copyable instead,
<code class="computeroutput"><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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> will
simply not copy <code class="computeroutput"><span class="identifier">x</span></code> at run-time
and leave <code class="computeroutput"><span class="identifier">old_x</span></code> initialized
as 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>
objects like <code class="computeroutput"><span class="identifier">old_x</span></code> must be
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
they are dereferenced in postconditions and exception guarantees.
</p>
<p>
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>
instead then this library would have generated a compile-time error when
<code class="computeroutput"><span class="identifier">offset</span></code> is instantiated with
types <code class="computeroutput"><span class="identifier">T</span></code> that are not copy
constructible (but only if <code class="computeroutput"><span class="identifier">old_x</span></code>
is actually dereferenced somewhere in the contract assertions using <code class="computeroutput"><span class="special">*</span><span class="identifier">old_x</span> <span class="special">...</span></code>, <code class="computeroutput"><span class="identifier">old_x</span><span class="special">-&gt;...</span></code>, etc.).
</p>
<p>
When C++11 <code class="computeroutput"><span class="keyword">auto</span></code> declarations
are used with <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>,
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>
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>).
If programmers want to relax the copyable type requirement, they must do
so explicitly by 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>
instead of using <code class="computeroutput"><span class="keyword">auto</span></code>. For example,
the following statements are equivalent:
</p>
<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>
<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">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">x</span><span class="special">)&gt;</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>
</pre>
<p>
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>
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>
to actually copy the old value. By default, <code class="computeroutput"><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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> and
<code class="computeroutput"><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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
implemented using <code class="computeroutput"><span class="identifier">T</span></code>'s copy
constructor. However, these type traits can be specialized by programmers
for example to avoid making old value copies of types even when they have
a copy constructor (maybe because these copy constructors are too expensive),
or to make old value copies for types that do not have a copy constructor,
or for any other specific need programmers might have for the types in question.
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>
intentionally avoids making old value copies for all expressions of type
<code class="computeroutput"><span class="identifier">w</span></code> even if that type has a
copy constructor (see <a href="../../../example/features/old_if_copyable.cpp" target="_top"><code class="literal">old_if_copyable.cpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Copyable type but...</span>
<span class="keyword">class</span> <span class="identifier">w</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">w</span><span class="special">(</span><span class="identifier">w</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">{</span> <span class="comment">/* Some very expensive copy here operation here... */</span> <span class="special">}</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// ...never copy old values for type `w` (because its copy is too expensive).</span>
<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>
<span class="keyword">template</span><span class="special">&lt;&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_old_value_copyable</span><span class="special">&lt;</span><span class="identifier">w</span><span class="special">&gt;</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">false_type</span> <span class="special">{};</span>
<span class="special">}</span> <span class="special">}</span>
</pre>
<p>
</p>
<p>
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>
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>
make old value copies of expressions of type <code class="computeroutput"><span class="identifier">p</span></code>
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>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Non-copyable type but...</span>
<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>
<span class="keyword">int</span><span class="special">*</span> <span class="identifier">num_</span><span class="special">;</span>
<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">&lt;</span><span class="identifier">p</span><span class="special">&gt;;</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// ...still copy old values for type `p` (using a deep copy).</span>
<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>
<span class="keyword">template</span><span class="special">&lt;&gt;</span>
<span class="keyword">struct</span> <span class="identifier">old_value_copy</span><span class="special">&lt;</span><span class="identifier">p</span><span class="special">&gt;</span> <span class="special">{</span>
<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">&amp;</span> <span class="identifier">old</span><span class="special">)</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="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>
<span class="special">}</span>
<span class="identifier">p</span> <span class="keyword">const</span><span class="special">&amp;</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>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">p</span> <span class="identifier">old_</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">template</span><span class="special">&lt;&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_old_value_copyable</span><span class="special">&lt;</span><span class="identifier">p</span><span class="special">&gt;</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">true_type</span> <span class="special">{};</span>
<span class="special">}</span> <span class="special">}</span>
</pre>
<p>
</p>
<h5>
<a name="boost_contract.extras.old_value_requirements__templates_.h0"></a>
<span class="phrase"><a name="boost_contract.extras.old_value_requirements__templates_.no_c__11"></a></span><a class="link" href="extras.html#boost_contract.extras.old_value_requirements__templates_.no_c__11">No
C++11</a>
</h5>
<p>
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>
require C++11 <code class="computeroutput"><span class="keyword">decltype</span></code> and SFINAE
to automatically detect if a given type is not copyable. On non-C++11 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>,
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
for more information). Alternatively, it is possible to 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>.
For example, for a non-copyable type <code class="computeroutput"><span class="identifier">n</span></code>
(see <a href="../../../example/features/old_if_copyable.cpp" target="_top"><code class="literal">old_if_copyable.cpp</code></a>):
</p>
<p>
</p>
<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>
<span class="keyword">int</span> <span class="identifier">num_</span><span class="special">;</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">n</span><span class="special">(</span><span class="identifier">n</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">// ...unimplemented private copy constructor (so non-copyable).</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Specialize `boost::is_copy_constructible` (no need for this on C++11).</span>
<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>
<span class="keyword">template</span><span class="special">&lt;&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_old_value_copyable</span><span class="special">&lt;</span><span class="identifier">n</span><span class="special">&gt;</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">false_type</span> <span class="special">{};</span>
<span class="special">}</span> <span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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
Requirements (Templates)</a>
</h3></div></div></div>
<p>
In general, assertions can introduce a new set of requirements on the types
used by the program. Some of these type requirements might be necessary only
to check the assertions and they would not be required by the program otherwise.
</p>
<p>
In some cases it might be acceptable, or even desirable, to cause a compile-time
error when a program uses types that do not provide all the operations needed
to check contract assertions (because it is not possible to fully check the
correctness of the program as specified by its contracts). In these cases,
programmers can specify contract assertions as we have seen so far, compilation
will fail if user types do not provide all operations necessary to check
the contracts.
</p>
<p>
However, in some other cases it might be desirable to not augment the type
requirements of a program because of contract assertions and to simply skip
these assertions when user types do not provide all the operations necessary
to check them, without causing compile-time errors. Programmers can do this
using <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
(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>).
</p>
<p>
For example, let's consider the following <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
class template equivalent to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>.
C++ <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> does
not require that its value type parameter <code class="computeroutput"><span class="identifier">T</span></code>
has an equality operator <code class="computeroutput"><span class="special">==</span></code>
(it only requires <code class="computeroutput"><span class="identifier">T</span></code> to be
copy constructible, see <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
documentation). However, the contracts for the <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">value</span><span class="special">)</span></code>
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>
that introduces the new requirement that <code class="computeroutput"><span class="identifier">T</span></code>
must also have an equality operator <code class="computeroutput"><span class="special">==</span></code>.
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>
<span class="special">==</span> <span class="identifier">value</span><span class="special">)</span></code> an let the program fail to compile when
users instantiate <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
with a type <code class="computeroutput"><span class="identifier">T</span></code> that does not
provide an equality operator <code class="computeroutput"><span class="special">==</span></code>.
Otherwise, programmers can specify this postcondition using <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
to evaluate the asserted condition only for types <code class="computeroutput"><span class="identifier">T</span></code>
that have an equality operator <code class="computeroutput"><span class="special">==</span></code>
(and trivially evaluate to <code class="computeroutput"><span class="keyword">true</span></code>
otherwise). On C++17 compilers, the same can be achieved using <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
instead of <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
resulting in a more concise and readable syntax. <a href="#ftn.boost_contract.extras.assertion_requirements__templates_.f0" class="footnote" name="boost_contract.extras.assertion_requirements__templates_.f0"><sup class="footnote">[69]</sup></a> For example (see <a href="../../../example/features/condition_if.cpp" target="_top"><code class="literal">condition_if.cpp</code></a>):
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Until C++17 (without <code class="computeroutput"><span class="keyword">if</span>
<span class="keyword">constexpr</span></code>)
</p>
</th>
<th>
<p>
Since C++17 (with <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>)
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<p>
</p>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</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">&amp;</span> <span class="identifier">value</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">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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="comment">// Instead of `ASSERT(back() == value)` for T without `==`.</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</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">condition_if</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;(</span>
<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">&lt;</span><span class="identifier">T</span><span class="special">&gt;(),</span>
<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>
<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>
<span class="special">)</span>
<span class="special">)</span>
<span class="special">);</span>
<span class="special">})</span>
<span class="special">;</span>
<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>
<span class="special">}</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
</td>
<td>
<p>
</p>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</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">&amp;</span> <span class="identifier">value</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">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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="comment">// Guard with `if constexpr` for T without `==`.</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">)</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<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>
<span class="special">}</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
</td>
</tr></tbody>
</table></div>
<p>
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>
is used as follow:
</p>
<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">&lt;</span><span class="identifier">Pred</span><span class="special">&gt;(</span>
<span class="identifier">cond</span>
<span class="special">)</span>
</pre>
<p>
Where <code class="computeroutput"><span class="identifier">Pred</span></code> is a nullary boolean
meta-function and <code class="computeroutput"><span class="identifier">cond</span></code> is
a nullary boolean functor. If <code class="computeroutput"><span class="identifier">Pred</span><span class="special">::</span><span class="identifier">value</span></code>
is statically evaluated to be <code class="computeroutput"><span class="keyword">true</span></code>
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
is returned by the enclosing <code class="computeroutput">boost::contract::condition_if</code>
call. Otherwise, if <code class="computeroutput"><span class="identifier">Pred</span><span class="special">::</span><span class="identifier">value</span></code>
is statically evaluated to be <code class="computeroutput"><span class="keyword">false</span></code>
at compile-time then <code class="computeroutput">boost::condition_if</code>
trivially returns <code class="computeroutput"><span class="keyword">true</span></code>. Therefore,
if <code class="computeroutput"><span class="identifier">cond</span></code> is a functor template
instantiation (not just a functor) then its call that contains the assertion
operations with the extra type requirements (e.g., the equality operator
<code class="computeroutput"><span class="special">==</span></code>) will not be actually instantiated
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>
(functor templates like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal_to</span></code>
and C++14 generic lambdas can be used to program <code class="computeroutput"><span class="identifier">cond</span></code>,
but C++11 lambdas cannot).
</p>
<p>
The <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
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>,
specifically <code class="computeroutput"><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">&lt;</span><span class="identifier">Pred</span><span class="special">&gt;(</span><span class="identifier">cond</span><span class="special">)</span></code> is
equivalent to <code class="computeroutput"><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">&lt;</span><span class="identifier">Pred</span><span class="special">&gt;(</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> <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">[70]</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>
function template accepts a number of optional <span class="emphasis"><em>else-if</em></span>
statements and one optional <span class="emphasis"><em>else</em></span> statement:
</p>
<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">&lt;</span><span class="identifier">Pred1</span><span class="special">&gt;(</span>
<span class="identifier">t1</span>
<span class="special">).</span><span class="keyword">template</span> <span class="identifier">else_if</span><span class="special">&lt;</span><span class="identifier">Pred2</span><span class="special">&gt;(</span> <span class="comment">// Optional.</span>
<span class="identifier">t2</span>
<span class="special">)</span>
<span class="special">...</span> <span class="comment">// Optionally, other `else_if` statements.</span>
<span class="special">.</span><span class="identifier">else_</span><span class="special">(</span> <span class="comment">// Optional for `void` functors, otherwise required.</span>
<span class="identifier">e</span>
<span class="special">)</span>
</pre>
<p>
Where <code class="computeroutput"><span class="identifier">Pred1</span></code>, <code class="computeroutput"><span class="identifier">Pred2</span></code>, ... are nullary boolean meta-functions
and <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> are nullary functors.
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 (possibly all
<code class="computeroutput"><span class="keyword">void</span></code>) or be of 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 call the functor <code class="computeroutput"><span class="identifier">t1</span><span class="special">()</span></code>, or <code class="computeroutput"><span class="identifier">t2</span><span class="special">()</span></code>, ..., or <code class="computeroutput"><span class="identifier">e</span><span class="special">()</span></code> depending on which meta-function <code class="computeroutput"><span class="identifier">Pred1</span><span class="special">::</span><span class="identifier">value</span></code>, <code class="computeroutput"><span class="identifier">Pred2</span><span class="special">::</span><span class="identifier">value</span></code>,
... is statically evaluated to be <code class="computeroutput"><span class="keyword">true</span></code>
or <code class="computeroutput"><span class="keyword">false</span></code> at compile-time, and
it will return the value returned by the functor being 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> are nullary functor
template instantiations (not just nullary functors) then their code will
only be compiled if the compiler determines they need to be actually called
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>,
<code class="computeroutput"><span class="identifier">Pred2</span><span class="special">::</span><span class="identifier">value</span></code>, ... are respectively evaluated to
be <code class="computeroutput"><span class="keyword">true</span></code> or <code class="computeroutput"><span class="keyword">false</span></code>
at compile-time). All the <code class="computeroutput"><span class="identifier">else_if</span><span class="special">&lt;...&gt;(...)</span></code> statements are optional.
The <code class="computeroutput"><span class="identifier">else_</span><span class="special">(...)</span></code>
statement is optional if the functor calls return <code class="computeroutput"><span class="keyword">void</span></code>,
otherwise it is required.
</p>
<p>
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>,
<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>,
and <code class="computeroutput"><span class="special">.</span><span class="identifier">else_if_c</span></code>
function templates work similarly to their counterparts without the <code class="computeroutput"><span class="special">...</span><span class="identifier">_c</span></code> postfix
seen so far, but they take their predicate template parameters as static
boolean values instead of nullary boolean meta-functions.
</p>
<p>
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>
can be used to program contract assertions that compile and check different
functor templates depending on related predicates being statically evaluated
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
<code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
should be sufficient and less verbose to use). On compilers that support
C++17 <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
there should be no need 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>
or <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>
because <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
can be used instead (making the code more readable and easier to program).
</p>
<h5>
<a name="boost_contract.extras.assertion_requirements__templates_.h0"></a>
<span class="phrase"><a name="boost_contract.extras.assertion_requirements__templates_.if_constexpr_emulation__c__14_"></a></span><a class="link" href="extras.html#boost_contract.extras.assertion_requirements__templates_.if_constexpr_emulation__c__14_">If-Constexpr
Emulation (C++14)</a>
</h5>
<p>
A part from its use within contracts, on C++14 compilers <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>
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>.
<a href="#ftn.boost_contract.extras.assertion_requirements__templates_.f2" class="footnote" name="boost_contract.extras.assertion_requirements__templates_.f2"><sup class="footnote">[71]</sup></a> For example (see <a href="../../../example/features/call_if_cxx14.cpp" target="_top"><code class="literal">call_if_cxx14.cpp</code></a>):
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Until C++17 (without <code class="computeroutput"><span class="keyword">if</span>
<span class="keyword">constexpr</span></code>)
</p>
</th>
<th>
<p>
Since C++17 (with <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>)
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<p>
</p>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">template</span><span class="special">&lt;</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">&gt;</span>
<span class="keyword">void</span> <span class="identifier">myadvance</span><span class="special">(</span><span class="identifier">Iter</span><span class="special">&amp;</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>
<span class="identifier">Iter</span><span class="special">*</span> <span class="identifier">p</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">i</span><span class="special">;</span> <span class="comment">// So captures change actual pointed iterator value.</span>
<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">&lt;</span><span class="identifier">is_random_access_iterator</span><span class="special">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;</span> <span class="special">&gt;(</span>
<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>
<span class="special">*</span><span class="identifier">p</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> <span class="identifier">n</span><span class="special">)</span>
<span class="special">).</span><span class="keyword">template</span> <span class="identifier">else_if</span><span class="special">&lt;</span><span class="identifier">is_bidirectional_iterator</span><span class="special">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;</span> <span class="special">&gt;(</span>
<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="keyword">if</span><span class="special">(</span><span class="identifier">n</span> <span class="special">&gt;=</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>
<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>
<span class="special">},</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">).</span><span class="keyword">template</span> <span class="identifier">else_if</span><span class="special">&lt;</span><span class="identifier">is_input_iterator</span><span class="special">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;</span> <span class="special">&gt;(</span>
<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="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>
<span class="special">},</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">).</span><span class="identifier">else_</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="special">(</span><span class="keyword">auto</span> <span class="identifier">false_</span><span class="special">)</span> <span class="special">{</span>
<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>
<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>
<span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
</p>
</td>
<td>
<p>
</p>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">template</span><span class="special">&lt;</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">&gt;</span>
<span class="keyword">void</span> <span class="identifier">myadvance</span><span class="special">(</span><span class="identifier">Iter</span><span class="special">&amp;</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>
<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">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">i</span> <span class="special">+=</span> <span class="identifier">n</span><span class="special">;</span>
<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">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">n</span> <span class="special">&gt;=</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>
<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>
<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">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">)</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>
<span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
<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>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
</p>
</td>
</tr></tbody>
</table></div>
<p>
This implementation is more concise, easier to read and maintain than the
usual implementation of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">advance</span></code>
that uses tag dispatching. Of course the implementation that uses C++17
<code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
is even more readable and concise.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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
Public Functions</a>
</h3></div></div></div>
<p>
This library allows to specify a different set of class invariants to check
for volatile public functions. These <span class="emphasis"><em>volatile class invariants</em></span>
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>,
taking no argument, and returning <code class="computeroutput"><span class="keyword">void</span></code>
(see <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870579312.html" title="Macro BOOST_CONTRACT_INVARIANT_FUNC">BOOST_CONTRACT_INVARIANT_FUNC</a></code>
to name the invariant function differently from <code class="computeroutput"><span class="identifier">invariant</span></code>
and <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access Specifiers</a>
to not have to declare it <code class="computeroutput"><span class="keyword">public</span></code>).
Classes that do no have invariants for their volatile public functions, simply
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.
</p>
<p>
In general, <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
invariants work the same as <code class="computeroutput"><span class="keyword">const</span></code>
invariants (see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class
Invariants</a>) with the only difference that <code class="computeroutput"><span class="keyword">volatile</span></code>
and <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
functions check <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
invariants while non-<code class="computeroutput"><span class="keyword">const</span></code> (i.e.,
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>
functions check <code class="computeroutput"><span class="keyword">const</span></code> invariants.
A given class can specify any combination of <code class="computeroutput"><span class="keyword">static</span></code>,
<code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>,
and <code class="computeroutput"><span class="keyword">const</span></code> invariant functions
(see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class Invariants</a>):
<a href="#ftn.boost_contract.extras.volatile_public_functions.f0" class="footnote" name="boost_contract.extras.volatile_public_functions.f0"><sup class="footnote">[72]</sup></a>
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Constructors check <code class="computeroutput"><span class="keyword">static</span></code>
invariants at entry and exit (even if an exception is thrown), plus
<code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
and <code class="computeroutput"><span class="keyword">const</span></code> invariants in
that order at exit but only if no exception is thrown.
</li>
<li class="listitem">
Destructors check <code class="computeroutput"><span class="keyword">static</span></code>
invariants at entry and exit (even if an exception is thrown), plus
<code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
and <code class="computeroutput"><span class="keyword">const</span></code> invariants in
that order at entry (and at exit but only if an exception is thrown,
even is destructors should in general never throw in C++).
</li>
<li class="listitem">
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>
invariants at entry and at exit (even if an exception is thrown).
</li>
<li class="listitem">
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>
public functions check <code class="computeroutput"><span class="keyword">static</span></code>
and <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
invariants at entry and at exit (even if an exception is thrown).
</li>
</ul></div>
<p>
These rules ensure that volatile class invariants are correctly checked (see
<a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constructor_calls" title="Constructor Calls">Constructor
Calls</a>, <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.destructor_calls" title="Destructor Calls">Destructor
Calls</a>, and <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.public_function_calls" title="Public Function Calls">Public
Function Calls</a>). For example (see <a href="../../../example/features/volatile.cpp" target="_top"><code class="literal">volatile.cpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<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>
<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>
<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>
<span class="identifier">u</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Check static, volatile, and const invariants.</span>
<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>
<span class="special">}</span>
<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>
<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="special">}</span>
<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>
<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>
<span class="special">}</span>
<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>
<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>
<span class="special">}</span>
<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>
<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>
<span class="special">}</span>
<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>
<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>
<span class="special">}</span>
<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>
<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">&lt;</span><span class="identifier">u</span><span class="special">&gt;();</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
This library does not automatically check <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">volatile</span></code> invariants for non-<code class="computeroutput"><span class="keyword">volatile</span></code> functions. However, if the contract
specifications require it, programmers can explicitly call the <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
invariant function from the <code class="computeroutput"><span class="keyword">const</span></code>
invariant function (preferably in that order to be consistent with the order
<code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
and <code class="computeroutput"><span class="keyword">const</span></code> invariants are checked
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>
invariants (while only <code class="computeroutput"><span class="keyword">const</span></code>
and non-<code class="computeroutput"><span class="keyword">const</span></code> public functions
will check only <code class="computeroutput"><span class="keyword">const</span></code> invariants,
correctly so because the <code class="computeroutput"><span class="keyword">volatile</span></code>
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">[73]</sup></a>
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<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>
<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="keyword">const_cast</span><span class="special">&lt;</span><span class="identifier">u</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">*&gt;(</span><span class="keyword">this</span><span class="special">)-&gt;</span><span class="identifier">invariant</span><span class="special">();</span> <span class="comment">// Call `const volatile` invariant function above.</span>
<span class="special">...</span> <span class="comment">// Other non-volatile invariants.</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="special">};</span>
</pre>
<p>
(As usual, private and protected functions do not check any invariant, not
even when they are <code class="computeroutput"><span class="keyword">volatile</span></code>
or <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>,
see <a class="link" href="advanced.html#boost_contract.advanced.private_and_protected_functions" title="Private and Protected Functions">Private
and Protected Functions</a>).
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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>
</h3></div></div></div>
<p>
As with all public operations of a class, also public move operations should
maintain class invariants (see <a class="link" href="bibliography.html#Stroustrup13_anchor">[Stroustrup13]</a>,
p. 520). Specifically, C++ requires the following:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
The moved-from object can be copy assigned.
</li>
<li class="listitem">
The moved-from object can be move assigned.
</li>
<li class="listitem">
The moved-from object can be destroyed (if not for anything else, this
requires that class invariants are maintained by move operations because
the destructor of the moved-from object requires class invariants 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
Calls</a>).
</li>
</ul></div>
<p>
Therefore, both the move constructor and the move assignment operator need
to maintain the class invariants of the moved-from object so their contracts
can be programmed using <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
and <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45123869756752.html" title="Function template public_function">boost::contract::public_function</a></code>
as usual. For example (see <a href="../../../example/features/move.cpp" target="_top"><code class="literal">move.cpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">circular_buffer</span> <span class="special">:</span>
<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">&lt;</span><span class="identifier">circular_buffer</span><span class="special">&gt;</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<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="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>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">index</span><span class="special">()</span> <span class="special">&lt;</span> <span class="identifier">size</span><span class="special">());</span>
<span class="special">}</span>
<span class="comment">// More invariants here that hold also for moved-from objects (e.g.,</span>
<span class="comment">// all assertions necessary to successfully destroy moved-from objects).</span>
<span class="special">}</span>
<span class="comment">// Move constructor.</span>
<span class="comment">/* implicit */</span> <span class="identifier">circular_buffer</span><span class="special">(</span><span class="identifier">circular_buffer</span><span class="special">&amp;&amp;</span> <span class="identifier">other</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">constructor_precondition</span><span class="special">&lt;</span><span class="identifier">circular_buffer</span><span class="special">&gt;([&amp;]</span> <span class="special">{</span>
<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>
<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">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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(!</span><span class="identifier">moved</span><span class="special">());</span>
<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>
<span class="special">})</span>
<span class="special">;</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">&lt;</span><span class="identifier">circular_buffer</span><span class="special">&gt;(</span><span class="identifier">other</span><span class="special">));</span>
<span class="special">}</span>
<span class="comment">// Move assignment.</span>
<span class="identifier">circular_buffer</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">circular_buffer</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">{</span>
<span class="comment">// Moved-from can be (move) assigned (so no pre `!moved()` here).</span>
<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>
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(!</span><span class="identifier">moved</span><span class="special">());</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<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">&lt;</span><span class="identifier">circular_buffer</span><span class="special">&gt;(</span><span class="identifier">other</span><span class="special">));</span>
<span class="special">}</span>
<span class="special">~</span><span class="identifier">circular_buffer</span><span class="special">()</span> <span class="special">{</span>
<span class="comment">// Moved-from can always be destroyed (in fact no preconditions).</span>
<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="special">}</span>
<span class="keyword">bool</span> <span class="identifier">moved</span><span class="special">()</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">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>
<span class="keyword">return</span> <span class="identifier">moved_</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">bool</span> <span class="identifier">moved_</span><span class="special">;</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
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>
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">[74]</sup></a>
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The default move constructor and move assignment operator generated by
C++ will not automatically check contracts. Therefore, unless the move
operations are not public or they have no preconditions, no postconditions,
and their class has no invariants, programmers should manually define them
using <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>,
<code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>,
and <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45123869756752.html" title="Function template public_function">boost::contract::public_function</a></code>
instead of relying on their default implementations generated by C++. (Same
as for all other operations automatically implemented by C++.)
</p></td></tr>
</table></div>
<p>
As always, programmers can decide to not program contracts for a given type.
Specifically, they might decide to not program contracts for a class that
needs to be moved in order to skip the run-time overhead of checking contract
assertions to optimize performance (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.benefits_and_costs" title="Benefits and Costs">Benefits
and Costs</a>).
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_contract.extras.unions"></a><a class="link" href="extras.html#boost_contract.extras.unions" title="Unions">Unions</a>
</h3></div></div></div>
<p>
In C++, a <code class="computeroutput"><span class="keyword">union</span></code> cannot have
virtual functions, bases classes, and cannot be used as a base class thus
subcontracting (<code class="computeroutput"><a class="link" href="../boost/contract/virtual_.html" title="Class virtual_">boost::contract::virtual_</a></code>,
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>,
etc.) do not apply to unions. Also a <code class="computeroutput"><span class="keyword">union</span></code>
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>
(because it cannot have base classes) so such a class is used to declare
a local object that checks constructor preconditions (at the very beginning
of the constructor before old value copies and other contracts, see declaration
of <code class="computeroutput"><span class="identifier">pre</span></code> in the example below).
A part from that, this library is used as usual to program contracts for
unions. For example (see <a href="../../../example/features/union.cpp" target="_top"><code class="literal">union.cpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">union</span> <span class="identifier">positive</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<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.</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="number">0</span><span class="special">);</span>
<span class="special">}</span>
<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.</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">i_</span> <span class="special">&gt;</span> <span class="number">0</span><span class="special">);</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">d_</span> <span class="special">&gt;</span> <span class="number">0</span><span class="special">);</span>
<span class="special">}</span>
<span class="comment">// Contracts for constructor, as usual but...</span>
<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="comment">// ...unions cannot have bases so constructor preconditions here.</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">&lt;</span><span class="identifier">positive</span><span class="special">&gt;</span> <span class="identifier">pre</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">&gt;</span> <span class="number">0</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">old_ptr</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <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>
<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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<span class="identifier">i_</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span>
<span class="special">++</span><span class="identifier">instances_</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// Contracts for destructor (as usual).</span>
<span class="special">~</span><span class="identifier">positive</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">old_ptr</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <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>
<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="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<span class="special">--</span><span class="identifier">instances_</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// Contracts for public function (as usual, but no virtual or override).</span>
<span class="keyword">void</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">x</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">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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">&gt;</span> <span class="number">0</span><span class="special">);</span>
<span class="special">});</span>
<span class="special">;</span>
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">i_</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// Contracts for static public function (as usual).</span>
<span class="keyword">static</span> <span class="keyword">int</span> <span class="identifier">instances</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">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">&lt;</span><span class="identifier">positive</span><span class="special">&gt;();</span>
<span class="keyword">return</span> <span class="identifier">instances_</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">int</span> <span class="identifier">i_</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">d_</span><span class="special">;</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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>
</h3></div></div></div>
<p>
This library provides three predefined <span class="emphasis"><em>assertion levels</em></span>
that can be used to selectively disable assertions depending on their computational
complexity: <a href="#ftn.boost_contract.extras.assertion_levels.f0" class="footnote" name="boost_contract.extras.assertion_levels.f0"><sup class="footnote">[75]</sup></a>
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
is used to assert conditions that are not computationally expensive,
at least compared to the cost of executing the function body. These assertions
are always checked at run-time, they are not disabled.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123871181520.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
is used to assert conditions that are computationally expensive compared
to the cost of executing the function body. These assertions are not
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>
(undefined by default), but the conditions are always compiled and validated
syntactically (even when they are not actually evaluated and checked
at run-time).
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123897980656.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
is used to assert conditions that are computationally prohibitive, at
least compared to the cost of executing the function body. These assertions
are never evaluated or checked at run-time, but the asserted conditions
are always compiled and validated syntactically so these assertions can
serve as formal comments in the code.
</li>
</ul></div>
<p>
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>
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>
are similar to <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123871181520.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123897980656.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
but they are used to program audit and axiom levels for implementation checks
instead of assertions (see <a class="link" href="advanced.html#boost_contract.advanced.implementation_checks" title="Implementation Checks">Implementation
Checks</a>).
</p>
<p>
For example, <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123871181520.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
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>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</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">&gt;</span>
<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>
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">RandomIter</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">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>
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">first</span> <span class="special">&lt;=</span> <span class="identifier">last</span><span class="special">);</span> <span class="comment">// Default, not expensive.</span>
<span class="comment">// Expensive O(n) assertion (use AXIOM if prohibitive instead).</span>
<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>
<span class="special">})</span>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
Similarly, <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_AUDITS.html" title="Macro BOOST_CONTRACT_AUDITS">BOOST_CONTRACT_AUDITS</a></code>
can be used to disable expensive old value copies and related assertions
that use them (see <a href="../../../example/features/assertion_level.cpp" target="_top"><code class="literal">assertion_level.cpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">vector</span><span class="special">&amp;</span> <span class="identifier">other</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">old_ptr</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span> <span class="identifier">old_me</span><span class="special">,</span> <span class="identifier">old_other</span><span class="special">;</span>
<span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_CONTRACT_AUDITS</span>
<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>
<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>
<span class="preprocessor">#endif</span> <span class="comment">// Else, skip old value copies...</span>
<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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="comment">// ...and also skip related assertions.</span>
<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>
<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>
<span class="special">})</span>
<span class="special">;</span>
<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>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"> <span class="comment">/* ... */</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">vect_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
The condition passed to <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123897980656.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
is compiled but not actually evaluated at run-time so this macro can be used
to program computationally prohibitive assertions but also assertions that
cannot actually be programmed in C++ using functions that are declared but
left undefined. For example, (see <a href="../../../example/features/assertion_level.cpp" target="_top"><code class="literal">assertion_level.cpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// If valid iterator range (cannot implement in C++ but OK to use in AXIOM).</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">&gt;</span>
<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>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
<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">&amp;</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">iterator</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">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</span> <span class="identifier">old_capacity</span> <span class="special">=</span>
<span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">capacity</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">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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="special">*</span><span class="identifier">old_capacity</span><span class="special">);</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">&gt;</span> <span class="special">*</span><span class="identifier">old_capacity</span><span class="special">)</span> <span class="special">{</span>
<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>
<span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
<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>
<span class="special">}</span>
<span class="special">})</span>
<span class="special">;</span>
<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>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"> <span class="comment">/* ... */</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">vect_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
In addition to the assertion levels predefined by this library, programmers
are free to define their own. For example, the following macro could be used
to program and selectively disable assertions that have exponential 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>:
</p>
<pre class="programlisting"><span class="preprocessor">#ifdef</span> <span class="identifier">NO_EXPONENTIALLY_COMPLEX_ASSERTIONS</span>
<span class="comment">// Following will compile but never actually evaluate `cond`.</span>
<span class="preprocessor">#define</span> <span class="identifier">EXP_ASSERTION</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>
<span class="preprocessor">#else</span>
<span class="comment">// Following will compile and also evaluate `cond`.</span>
<span class="preprocessor">#define</span> <span class="identifier">EXP_ASSERTION</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>
<span class="preprocessor">#endif</span>
<span class="special">...</span>
<span class="identifier">EXP_ASSERTION</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>some-exponentially-complex-boolean-condition</em></span></code><span class="special">);</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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
Contract Checking</a>
</h3></div></div></div>
<p>
Checking contracts adds run-time overhead and can slow down program execution
(see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.benefits_and_costs" title="Benefits and Costs">Benefits
and Costs</a>). Therefore, programmers can define any combination of the
following macros (<code class="computeroutput"><span class="special">-</span><span class="identifier">D</span></code>
option in Clang and GCC, <code class="computeroutput"><span class="special">/</span><span class="identifier">D</span></code>
option in MSVC, etc.) to instruct this library to not check specific kind
of contract conditions at run-time:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870517808.html" title="Macro BOOST_CONTRACT_NO_PRECONDITIONS">BOOST_CONTRACT_NO_PRECONDITIONS</a></code>
to not check preconditions.
</li>
<li class="listitem">
Define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870511440.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>
to not check postconditions.
</li>
<li class="listitem">
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>
to not check exception guarantees.
</li>
<li class="listitem">
Define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870492704.html" title="Macro BOOST_CONTRACT_NO_ENTRY_INVARIANTS">BOOST_CONTRACT_NO_ENTRY_INVARIANTS</a></code>
to not check class invariants at call entry.
</li>
<li class="listitem">
Define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870485088.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>
to not check class invariants at call exit.
</li>
<li class="listitem">
Or, define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870477472.html" title="Macro BOOST_CONTRACT_NO_INVARIANTS">BOOST_CONTRACT_NO_INVARIANTS</a></code>
to not check class invariants at both call entry and exit. (This is provided
for convenience, it is equivalent to define both <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870492704.html" title="Macro BOOST_CONTRACT_NO_ENTRY_INVARIANTS">BOOST_CONTRACT_NO_ENTRY_INVARIANTS</a></code>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870485088.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>.)
</li>
<li class="listitem">
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>
to not perform implementation checks.
</li>
</ul></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Old values can be used by both postconditions and exception guarantees
so it is necessary to define both <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870511440.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>
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>
to disable old value copies.
</p></td></tr>
</table></div>
<p>
By default, none of these macros are defined so this library checks all contracts.
When these macros are defined by the user, the implementation code of this
library is internally optimized to minimize as much as possible any run-time
and compile-time overhead associated with checking and compiling contracts
(see <a class="link" href="extras.html#boost_contract.extras.disable_contract_compilation__macro_interface_" title="Disable Contract Compilation (Macro Interface)">Disable
Contract Compilation</a> for techniques to completely remove any run-time
and compile-time overhead associated with contract code).
</p>
<p>
For example, programmers could decide to check all contracts during early
development builds, but later check only preconditions and maybe entry invariants
for release builds by defining <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870511440.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>,
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>,
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870485088.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>,
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>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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
Contract Compilation (Macro Interface)</a>
</h3></div></div></div>
<p>
This library provides macros that can be used to completely disable compile-time
and run-time overhead introduced by contracts but at the cost of manually
programming <code class="computeroutput"><span class="preprocessor">#ifndef</span></code> statements
around contract code:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
This library defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870460880.html" title="Macro BOOST_CONTRACT_NO_CONSTRUCTORS">BOOST_CONTRACT_NO_CONSTRUCTORS</a></code>
when contract checking is disabled for constructors.
</li>
<li class="listitem">
This library defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870450032.html" title="Macro BOOST_CONTRACT_NO_DESTRUCTORS">BOOST_CONTRACT_NO_DESTRUCTORS</a></code>
when contract checking is disabled for destructors.
</li>
<li class="listitem">
This library defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870441776.html" title="Macro BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</a></code>
when contract checking is disabled for public functions.
</li>
<li class="listitem">
This library defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870432592.html" title="Macro BOOST_CONTRACT_NO_FUNCTIONS">BOOST_CONTRACT_NO_FUNCTIONS</a></code>
when contract checking is disabled for (non-public and non-member) functions.
</li>
<li class="listitem">
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>
when old value copies are disabled.
</li>
<li class="listitem">
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>
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>)
are disabled.
</li>
</ul></div>
<p>
These macros are not configuration macros and they should not be defined
directly by programmers (otherwise this library will generate a compile-time
error). Instead, these macros are automatically defined by this library when
programmers define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870517808.html" title="Macro BOOST_CONTRACT_NO_PRECONDITIONS">BOOST_CONTRACT_NO_PRECONDITIONS</a></code>,
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870511440.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>,
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>,
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870477472.html" title="Macro BOOST_CONTRACT_NO_INVARIANTS">BOOST_CONTRACT_NO_INVARIANTS</a></code>
(or <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870492704.html" title="Macro BOOST_CONTRACT_NO_ENTRY_INVARIANTS">BOOST_CONTRACT_NO_ENTRY_INVARIANTS</a></code>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870485088.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>),
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>
(see <a class="link" href="extras.html#boost_contract.extras.disable_contract_checking" title="Disable Contract Checking">Disable
Contract Checking</a>).
</p>
<p>
Alternatively, this library provides a macro-based interface <code class="computeroutput"><a class="link" href="../reference.html#header.boost.contract_macro_hpp" title="Header &lt;boost/contract_macro.hpp&gt;">boost/contract_macro.hpp</a></code> that
can also be used to completely disable compile-time and run-time overhead
introduced by contracts. For example, the following code shows how to use
both the macro interface and the <code class="computeroutput"><span class="preprocessor">#ifndef</span>
<span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
statements to completely disable compile-time and run-time overhead for non-member
function contracts (see <a href="../../../example/features/ifdef_macro.cpp" target="_top"><code class="literal">ifdef_macro.cpp</code></a>
and <a href="../../../example/features/ifdef.cpp" target="_top"><code class="literal">ifdef.cpp</code></a>):
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Macro Interface
</p>
</th>
<th>
<p>
<code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> Statements
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<p>
</p>
<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>
<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
<span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">result</span><span class="special">;</span>
<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>
<span class="identifier">BOOST_CONTRACT_FUNCTION</span><span class="special">()</span>
<span class="identifier">BOOST_CONTRACT_PRECONDITION</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">());</span>
<span class="special">})</span>
<span class="identifier">BOOST_CONTRACT_POSTCONDITION</span><span class="special">([&amp;]</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="number">1</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="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
<span class="special">})</span>
<span class="special">;</span>
<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="special">}</span>
</pre>
<p>
</p>
</td>
<td>
<p>
</p>
<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>
<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_ALL</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
<span class="preprocessor">#endif</span>
<span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">result</span><span class="special">;</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_OLDS</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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="preprocessor">#endif</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_FUNCTIONS</span>
<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>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PRECONDITIONS</span>
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">());</span>
<span class="special">})</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_POSTCONDITIONS</span>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</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="number">1</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="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
<span class="special">})</span>
<span class="preprocessor">#endif</span>
<span class="special">;</span>
<span class="preprocessor">#endif</span>
<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="special">}</span>
</pre>
<p>
</p>
</td>
</tr></tbody>
</table></div>
<p>
The same can be done to disable contract code complication for private and
protected functions. The <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123869551136.html" title="Macro BOOST_CONTRACT_OLD_PTR_IF_COPYABLE">BOOST_CONTRACT_OLD_PTR_IF_COPYABLE</a></code>
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>).
For constructors, destructors, and public functions instead (see <a href="../../../example/features/ifdef_macro.cpp" target="_top"><code class="literal">ifdef_macro.cpp</code></a>
and <a href="../../../example/features/ifdef.cpp" target="_top"><code class="literal">ifdef.cpp</code></a>):
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Macro Interface
</p>
</th>
<th>
<p>
<code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> Statements
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<p>
</p>
<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>
<span class="preprocessor">#define</span> <span class="identifier">BASES</span> <span class="keyword">public</span> <span class="identifier">pushable</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span>
<span class="special">:</span>
<span class="comment">// Left in code (almost no overhead).</span>
<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">&lt;</span><span class="identifier">integers</span><span class="special">&gt;,</span>
<span class="identifier">BASES</span>
<span class="special">{</span>
<span class="comment">// Followings left in code (almost no overhead).</span>
<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>
<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>
<span class="preprocessor">#undef</span> <span class="identifier">BASES</span>
<span class="identifier">BOOST_CONTRACT_INVARIANT</span><span class="special">({</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;=</span> <span class="identifier">capacity</span><span class="special">());</span>
<span class="special">})</span>
<span class="keyword">public</span><span class="special">:</span>
<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>
<span class="identifier">BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION</span><span class="special">(</span><span class="identifier">integers</span><span class="special">)([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">from</span> <span class="special">&lt;=</span> <span class="identifier">to</span><span class="special">);</span>
<span class="special">}),</span>
<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>
<span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_CONSTRUCTOR</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
<span class="identifier">BOOST_CONTRACT_POSTCONDITION</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<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">&lt;=</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>
<span class="special">}</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">integers</span><span class="special">()</span> <span class="special">{</span>
<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>
<span class="special">}</span>
<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="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</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="comment">// Left in code (almost no overhead).</span>
<span class="special">)</span> <span class="comment">/* override */</span> <span class="special">{</span>
<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>
<span class="identifier">BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE</span><span class="special">(</span><span class="identifier">override_push_back</span><span class="special">)(</span>
<span class="identifier">v</span><span class="special">,</span> <span class="special">&amp;</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>
<span class="identifier">BOOST_CONTRACT_PRECONDITION</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;</span> <span class="identifier">max_size</span><span class="special">());</span>
<span class="special">})</span>
<span class="identifier">BOOST_CONTRACT_OLD</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="identifier">BOOST_CONTRACT_POSTCONDITION</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="identifier">BOOST_CONTRACT_EXCEPT</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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="special">})</span>
<span class="special">;</span>
<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>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<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>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
</td>
<td>
<p>
</p>
<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>
<span class="preprocessor">#define</span> <span class="identifier">BASES</span> <span class="keyword">public</span> <span class="identifier">pushable</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span>
<span class="special">:</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PRECONDITIONS</span>
<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">&lt;</span><span class="identifier">integers</span><span class="special">&gt;,</span> <span class="identifier">BASES</span>
<span class="preprocessor">#else</span>
<span class="identifier">BASES</span>
<span class="preprocessor">#endif</span>
<span class="special">{</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_ALL</span>
<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>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</span>
<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>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#undef</span> <span class="identifier">BASES</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_INVARIANTS</span>
<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="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;=</span> <span class="identifier">capacity</span><span class="special">());</span>
<span class="special">}</span>
<span class="preprocessor">#endif</span>
<span class="keyword">public</span><span class="special">:</span>
<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>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PRECONDITIONS</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">&lt;</span><span class="identifier">integers</span><span class="special">&gt;([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">from</span> <span class="special">&lt;=</span> <span class="identifier">to</span><span class="special">);</span>
<span class="special">}),</span>
<span class="preprocessor">#endif</span>
<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>
<span class="special">{</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_CONSTRUCTORS</span>
<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>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_POSTCONDITIONS</span>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="preprocessor">#endif</span>
<span class="special">;</span>
<span class="preprocessor">#endif</span>
<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">&lt;=</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>
<span class="special">}</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">integers</span><span class="special">()</span> <span class="special">{</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_DESTRUCTORS</span>
<span class="comment">// Check invariants.</span>
<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="preprocessor">#endif</span>
<span class="special">}</span>
<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="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</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="preprocessor">#endif</span>
<span class="special">)</span> <span class="comment">/* override */</span> <span class="special">{</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_OLDS</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">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</span> <span class="identifier">old_size</span><span class="special">;</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</span>
<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">&lt;</span>
<span class="identifier">override_push_back</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">,</span> <span class="special">&amp;</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>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PRECONDITIONS</span>
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;</span> <span class="identifier">max_size</span><span class="special">());</span>
<span class="special">})</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_OLDS</span>
<span class="special">.</span><span class="identifier">old</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_POSTCONDITIONS</span>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_EXCEPTS</span>
<span class="special">.</span><span class="identifier">except</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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="special">})</span>
<span class="preprocessor">#endif</span>
<span class="special">;</span>
<span class="preprocessor">#endif</span>
<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>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS</span>
<span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">push_back</span><span class="special">)</span>
<span class="preprocessor">#endif</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
</td>
</tr></tbody>
</table></div>
<p>
Static and volatile class invariants can be programmed using <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123869498768.html" title="Macro BOOST_CONTRACT_STATIC_INVARIANT">BOOST_CONTRACT_STATIC_INVARIANT</a></code>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123869512624.html" title="Macro BOOST_CONTRACT_INVARIANT_VOLATILE">BOOST_CONTRACT_INVARIANT_VOLATILE</a></code>
respectively (these macros expand code equivalent to the <code class="computeroutput"><span class="keyword">static</span>
<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>
<span class="identifier">BOOST_CONTRACT_INVARIANT_FUNC</span><span class="special">()</span>
<span class="keyword">const</span> <span class="keyword">volatile</span></code>
functions).
</p>
<p>
The macro interface is usually preferred because more concise and easier
to use than programming <code class="computeroutput"><span class="preprocessor">#ifndef</span>
<span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
statements by hand. However, C++ macros expand on a single line of code and
that can make compiler errors less useful when using the macro interface
plus all contract assertions within a given set of preconditions, postconditions,
exception guarantees, and class invariants will list the same line number
in error messages when assertions fail at run-time (but error messages still
list the assertion code and that should allow programmers to identify the
specific assertion that failed). Finally, the macro interface leaves a bit
of contract decorations in the code but that should add no measurable compile-time
and 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>
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>
<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>
friendships are left in user code even when contracts are disabled).
</p>
<p>
Disabling contract as shown in <a class="link" href="extras.html#boost_contract.extras.disable_contract_checking" title="Disable Contract Checking">Disable
Contract Checking</a> leaves the overhead of compiling contract code plus
some small run-time overhead due to the initialization of old value pointers
(even if those will be all null and no old value will be actually copied),
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>
and <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
(even if those calls will be internally optimized by this library to essentially
do nothing), etc. For truly performance critical code for which even such
small run-time overhead might not be acceptable, the macro interface (or
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
disable compile-time and run-time overheads of contracts. However, for such
performance critical code even the overhead of checking simple preconditions
might be too much so it might be best to not program contracts at all.
</p>
<p>
Usually, if the overhead of checking preconditions and other assertions is
already considered acceptable for an application then the compile-time overhead
of contracts should not represent an issue and it should be sufficient to
be able to 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
Contract Checking</a> (without a real need to use the macro interface
or the <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> statements in most cases).
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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
Body Implementation</a>
</h3></div></div></div>
<p>
Contracts are part of the program specifications and not of its implementation
(see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.specifications_vs__implementation" title="Specifications vs. Implementation">Specifications
vs. Implementation</a>). However, this library uses function definitions
to program contracts so contract code appears together with the function
implementation code. This is not ideal (even if contracts programmed using
this library will always appear at the very beginning of the function definition
so programmers will easily be able to distinguish contract code from the
rest of the function implementation code so this might not be real limitation
in practise).
</p>
<p>
In some cases, it might be desirable to completely separate the contract
code from the function implementation code. For example, this could be necessary
for software that ships only header files and compiled object files to its
users. If contracts are programmed in function definitions that are compiled
in the object files, users will not be able to see the contract code to understand
semantics and usage of the functions (again, this might not be a real problem
in practice for example if contracts are already somehow extracted from the
source code by some toll and presented as part of the documentation of the
shipped software).
</p>
<p>
In any case, when it is truly important to separate contracts from function
implementation code, function implementations can be programmed in extra
<span class="emphasis"><em>body functions</em></span> (e.g., named <code class="computeroutput"><span class="special">...</span><span class="identifier">_body</span></code>) that are compiled in object files.
Function definitions that remain in header files instead will contain just
contract code followed by calls the extra body functions. This technique
allows to keep the contract code in header files while separating the implementation
code to object files. However, it adds the overhead of manually programming
an extra function declaration for the body function (plus the limitation
that constructor member initialization lists must be programmed in header
files because that is where constructors need to be defined to list constructor
contract code). <a href="#ftn.boost_contract.extras.separate_body_implementation.f0" class="footnote" name="boost_contract.extras.separate_body_implementation.f0"><sup class="footnote">[76]</sup></a>
</p>
<p>
For example, the following header file only contains function declarations,
contract code, and constructor member initializations, but it does not contain
the code implementing the function bodies (see <a href="../../../example/features/separate_body.hpp" target="_top"><code class="literal">separate_body.hpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">iarray</span> <span class="special">:</span>
<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">&lt;</span><span class="identifier">iarray</span><span class="special">&gt;</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<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="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;=</span> <span class="identifier">capacity</span><span class="special">());</span>
<span class="special">}</span>
<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>
<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">&lt;</span><span class="identifier">iarray</span><span class="special">&gt;([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">count</span> <span class="special">&lt;=</span> <span class="identifier">max</span><span class="special">);</span>
<span class="special">}),</span>
<span class="comment">// Still, member initializations must be here.</span>
<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="identifier">capacity_</span><span class="special">(</span><span class="identifier">max</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">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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<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>
<span class="special">})</span>
<span class="special">;</span>
<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>
<span class="special">}</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">iarray</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">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>
<span class="identifier">destructor_body</span><span class="special">();</span> <span class="comment">// Separate destructor body implementation.</span>
<span class="special">}</span>
<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>
<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">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</span> <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>
<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>
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;</span> <span class="identifier">capacity</span><span class="special">());</span>
<span class="special">})</span>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<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>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="comment">// Contracts in class declaration (above), but body implementations are not.</span>
<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>
<span class="keyword">void</span> <span class="identifier">destructor_body</span><span class="special">();</span>
<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>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
Instead, the function bodies are implemented in a separate source file (see
<a href="../../../example/features/separate_body.cpp" target="_top"><code class="literal">separate_body.cpp</code></a>):
</p>
<p>
</p>
<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>
<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">&lt;</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>
<span class="identifier">size_</span> <span class="special">=</span> <span class="identifier">count</span><span class="special">;</span>
<span class="special">}</span>
<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>
<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>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
The same technique can be used for non-member, private, protectee functions,
etc.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top">
<p>
When contracts are programmed only in <code class="literal">.cpp</code> files and
also all this library headers are <code class="computeroutput"><span class="preprocessor">#include</span></code>d
only from <code class="literal">.cpp</code> files, then these <code class="literal">.cpp</code>
files can be compiled disabling specific contract checking (for example,
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870511440.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>,
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>,
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870485088.html" title="Macro BOOST_CONTRACT_NO_EXIT_INVARIANTS">BOOST_CONTRACT_NO_EXIT_INVARIANTS</a></code>,
see <a class="link" href="extras.html#boost_contract.extras.disable_contract_checking" title="Disable Contract Checking">Disable
Contract Checking</a>). Then the code in these <code class="literal">.cpp</code>
files will always have such contract checking disabled even when linked
to some other user code that might have been compiled with a different
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
be useful to ship compiled object files (e.g., for a library) that will
never check some contracts (e.g., postconditions, exception guarantees,
and exit invariants) regardless of the definition of the <code class="computeroutput"><span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
macros used to compile code that links against the shipped object files.
</p>
<p>
On the flip side, if contracts are programmed only in header files (e.g.,
using extra <code class="computeroutput"><span class="special">...</span><span class="identifier">_body</span></code>
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
that are being shipped, then end users can enable or disables contract
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
header files as part of their code. This technique might be useful in other
situations when programmers that ship code want to leave it up the their
end users to decide which contracts of the shipped code should be checked
at run-time.
</p>
</td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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
Lambda Functions (No C++11)</a>
</h3></div></div></div>
<p>
This section shows how to use this library without C++11 lambda functions.
This has some advantages:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
It allows to use this library on compilers that do not support C++11
lambda functions (essentially most C++03 compilers with adequate support
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
Macros</a> to also avoid using variadic macros).
</li>
<li class="listitem">
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
below) can be programmed to fully enforce constant-correctness and other
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>).
<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">[77]</sup></a>
</li>
<li class="listitem">
Code of the contract functions is separated from function body implementations
(see <a class="link" href="extras.html#boost_contract.extras.separate_body_implementation" title="Separate Body Implementation">Separate
Body Implementation</a>). <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">[78]</sup></a>
</li>
</ul></div>
<p>
However, not using C++11 lambda functions comes at the significant cost of
having to manually program the extra contract functions and related boiler-plate
code. For example (see <a href="../../../example/features/no_lambdas.hpp" target="_top"><code class="literal">no_lambdas.hpp</code></a>
and <a href="../../../example/features/no_lambdas.cpp" target="_top"><code class="literal">no_lambdas.cpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">iarray</span> <span class="special">:</span>
<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">&lt;</span><span class="identifier">iarray</span><span class="special">&gt;</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<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="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="number">0</span><span class="special">);</span>
<span class="special">}</span>
<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="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;=</span> <span class="identifier">capacity</span><span class="special">());</span>
<span class="special">}</span>
<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="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>
<span class="keyword">unsigned</span> <span class="keyword">const</span> <span class="identifier">count</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">count</span> <span class="special">&lt;=</span> <span class="identifier">max</span><span class="special">);</span>
<span class="special">}</span>
<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">&lt;</span><span class="keyword">int</span><span class="special">&gt;&amp;</span>
<span class="identifier">old_instances</span><span class="special">)</span> <span class="special">{</span>
<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>
<span class="special">}</span>
<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>
<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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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>
<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>
<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>
<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>
<span class="special">}</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">iarray</span><span class="special">();</span>
<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">&lt;</span><span class="keyword">int</span><span class="special">&gt;&amp;</span> <span class="identifier">old_instances</span><span class="special">)</span>
<span class="keyword">const</span> <span class="special">{</span>
<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>
<span class="special">}</span>
<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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span>
<span class="identifier">old_instances</span><span class="special">)</span> <span class="special">{</span>
<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>
<span class="special">}</span>
<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="keyword">void</span> <span class="identifier">push_back_precondition</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;</span> <span class="identifier">capacity</span><span class="special">());</span>
<span class="special">}</span>
<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>
<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">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;&amp;</span> <span class="identifier">old_size</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
<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>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">push_back_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">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</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>
<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>
<span class="special">}</span>
<span class="keyword">unsigned</span> <span class="identifier">capacity</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">unsigned</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">static</span> <span class="keyword">int</span> <span class="identifier">instances</span><span class="special">();</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">int</span><span class="special">*</span> <span class="identifier">values_</span><span class="special">;</span>
<span class="keyword">unsigned</span> <span class="identifier">capacity_</span><span class="special">;</span>
<span class="keyword">unsigned</span> <span class="identifier">size_</span><span class="special">;</span>
<span class="keyword">static</span> <span class="keyword">int</span> <span class="identifier">instances_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
</p>
<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>
<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">&lt;</span><span class="identifier">iarray</span><span class="special">&gt;(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span>
<span class="special">&amp;</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>
<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>
<span class="identifier">capacity_</span><span class="special">(</span><span class="identifier">max</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">old_ptr</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">old_instances</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">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>
<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">(&amp;</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>
<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="special">&amp;</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">constructor_postcondition</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">max</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">count</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">old_instances</span><span class="special">)</span>
<span class="special">))</span>
<span class="special">;</span>
<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">&lt;</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>
<span class="identifier">size_</span> <span class="special">=</span> <span class="identifier">count</span><span class="special">;</span>
<span class="special">++</span><span class="identifier">instances_</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">iarray</span><span class="special">::~</span><span class="identifier">iarray</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">old_ptr</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">old_instances</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">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="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">(&amp;</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>
<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>
<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">(&amp;</span><span class="identifier">iarray</span><span class="special">::</span><span class="identifier">destructor_postcondition</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">old_instances</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><span class="identifier">instances_</span><span class="special">;</span>
<span class="special">}</span>
<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>
<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">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</span> <span class="identifier">old_size</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">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>
<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">(&amp;</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>
<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">(&amp;</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>
<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>
<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">(&amp;</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>
<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>
<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>
<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>
<span class="comment">// Check invariants.</span>
<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>
<span class="keyword">return</span> <span class="identifier">capacity_</span><span class="special">;</span>
<span class="special">}</span>
<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>
<span class="comment">// Check invariants.</span>
<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>
<span class="keyword">return</span> <span class="identifier">size_</span><span class="special">;</span>
<span class="special">}</span>
<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>
<span class="comment">// Check static invariants.</span>
<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">&lt;</span><span class="identifier">iarray</span><span class="special">&gt;();</span>
<span class="keyword">return</span> <span class="identifier">instances_</span><span class="special">;</span>
<span class="special">}</span>
<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>
</pre>
<p>
</p>
<p>
If programmers also want to fully enforce all contract programming constant-correctness
requirements at compile-time, they should follow these rules when programming
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>):
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Precondition functions (i.e., the <code class="computeroutput"><span class="special">...</span><span class="identifier">_precondition</span></code> functions in the example
above) can take their arguments either by <code class="computeroutput"><span class="keyword">const</span></code>
value or by <code class="computeroutput"><span class="keyword">const</span><span class="special">&amp;</span></code>,
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>
functions.
</li>
<li class="listitem">
Postcondition functions (i.e., the <code class="computeroutput"><span class="special">...</span><span class="identifier">_postcondition</span></code> functions in the example
above) should take their arguments by <code class="computeroutput"><span class="keyword">const</span><span class="special">&amp;</span></code>, 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> functions.
</li>
<li class="listitem">
Similarly, exception guarantee functions (not shown in the example above)
should take their arguments by <code class="computeroutput"><span class="keyword">const</span><span class="special">&amp;</span></code>, 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> functions.
</li>
<li class="listitem">
Old value functions (i.e., the <code class="computeroutput"><span class="special">...</span><span class="identifier">_old</span></code> functions in the example above)
should take their arguments by <code class="computeroutput"><span class="keyword">const</span><span class="special">&amp;</span></code> a part from old value pointers that
should be taken by <code class="computeroutput"><span class="special">&amp;</span></code>
(so only old value pointers can be modified), 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> functions.
</li>
<li class="listitem">
Constructor precondition, old value, and exception guarantee functions
should be <code class="computeroutput"><span class="keyword">static</span></code> (because
there is no valid object <code class="computeroutput"><span class="keyword">this</span></code>
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
Calls</a>).
</li>
<li class="listitem">
Destructor postcondition functions should be <code class="computeroutput"><span class="keyword">static</span></code>
(because there is no valid object <code class="computeroutput"><span class="keyword">this</span></code>
after the destructor body runs successfully, but exception guarantee
functions do not have to be <code class="computeroutput"><span class="keyword">static</span></code>
since the object <code class="computeroutput"><span class="keyword">this</span></code> is
still valid because the destructor body did not run successfully, see
<a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.destructor_calls" title="Destructor Calls">Destructor
Calls</a>).
</li>
</ul></div>
<p>
Note that the extra contract functions also allow to keep the contract code
in the header file while all function bodies are implemented in a separate
source file (including the constructor member initialization list, that could
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
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">[79]</sup></a> Also note that the contract functions can always be declared
<code class="computeroutput"><span class="keyword">private</span></code> if programmers need
to exactly control the public members of the class (this was not done in
this example only for brevity).
</p>
<p>
The authors think this library is most useful when used together with C++11
lambda functions.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<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
Macros (and No Variadic Macros)</a>
</h3></div></div></div>
<p>
It is possible to specify contracts without using most of the macros provided
by this library and programming the related code manually instead (the only
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>,
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDES.html" title="Macro BOOST_CONTRACT_OVERRIDES">BOOST_CONTRACT_OVERRIDES</a></code>,
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123869781472.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>).
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Some of this library macros are variadic macros, others are not (see below).
Variadic macros were officially added to the language in C++11 but most
compilers have been supporting them as an extension for a long time, plus
all compilers that support C++11 lambda functions should also support C++11
variadic macros (and this library might rarely be used without the convenience
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
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">[80]</sup></a> Therefore, the rest of this section can be considered mainly
a curiosity because programmers should seldom, if ever, need to use this
library without using its macros.
</p></td></tr>
</table></div>
<h5>
<a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h0"></a>
<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>
</h5>
<p>
As shown in <a class="link" href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public
Function Overrides</a> and <a class="link" href="advanced.html#boost_contract.advanced.named_overrides" title="Named Overrides">Named
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>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123869781472.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>
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
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">[81]</sup></a> These macro cannot be programmed manually but they are not variadic
macros (so programmers should be able to use them on any C++ compiler with
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">[82]</sup></a> The <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDES.html" title="Macro BOOST_CONTRACT_OVERRIDES">BOOST_CONTRACT_OVERRIDES</a></code>
macro is a variadic macro instead but programmes can manually repeat the
non-variadic macro <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>
for each overriding public function name on compilers that do not support
variadic macros.
</p>
<h5>
<a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h1"></a>
<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
(Not Variadic)</a>
</h5>
<p>
As shown in <a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a>,
<a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>,
<a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception Guarantees</a>,
<a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class Invariants</a>,
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>
macro to assert contract conditions. This is not a variadic macro and programmers
should be able to use it on all C++ compilers. In any case, the invocation
<code class="computeroutput"><span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</span></code> expands
to code equivalent to the 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">[83]</sup></a>
</p>
<pre class="programlisting"><span class="keyword">if</span><span class="special">(!(</span><span class="identifier">cond</span><span class="special">))</span> <span class="special">{</span>
<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>
<span class="identifier">BOOST_PP_STRINGIZE</span><span class="special">(</span><span class="identifier">cond</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<p>
In fact, this library considers any exception thrown from within preconditions,
postconditions, exception guarantees, and class invariants as a contract
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>,
etc.). If there is a need for it, programmers can always program contract
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
on Failures</a>):
</p>
<pre class="programlisting"><span class="keyword">if</span><span class="special">(!</span><span class="identifier">cond</span><span class="special">)</span> <span class="keyword">throw</span> <span class="identifier">exception_object</span><span class="special">;</span>
</pre>
<p>
However, using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
is convenient because it always allows this library to show an informative
message in case of assertion failure containing the assertion code, file
name, line number, etc.
</p>
<p>
The <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123871181520.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123897980656.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
macros are not variadic macros and programmers should be able to use them
on all C++ compilers. Their implementations are equivalent to the following:
</p>
<pre class="programlisting"><span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_CONTRACT_AUDITS</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTRACT_ASSERT_AUDIT</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</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>
<span class="preprocessor">#else</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTRACT_ASSERT_AUDIT</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</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>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTRACT_ASSERT_AXIOM</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</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>
</pre>
<h5>
<a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h2"></a>
<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
Types (Variadic)</a>
</h5>
<p>
As shown in <a class="link" href="tutorial.html#boost_contract.tutorial.base_classes__subcontracting_" title="Base Classes (Subcontracting)">Base
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>
variadic macro to declare the <code class="computeroutput"><span class="identifier">base_types</span></code>
member type that will expand to the list of all public bases for a derived
class. Programmers can also declare <code class="computeroutput"><span class="identifier">base_types</span></code>
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>
at the cost of writing a bit more code and increase maintenance efforts.
For example (see <a href="../../../example/features/base_types_no_macro.cpp" target="_top"><code class="literal">base_types_no_macro.cpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
<span class="keyword">class</span> <span class="identifier">chars</span> <span class="special">:</span>
<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">&lt;</span><span class="identifier">chars</span><span class="special">&gt;,</span>
<span class="keyword">public</span> <span class="identifier">unique_chars</span><span class="special">,</span>
<span class="keyword">public</span> <span class="keyword">virtual</span> <span class="identifier">pushable</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;,</span>
<span class="keyword">virtual</span> <span class="keyword">protected</span> <span class="identifier">has_size</span><span class="special">,</span>
<span class="keyword">private</span> <span class="identifier">has_empty</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// Program `base_types` without macros (list only public bases).</span>
<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">&lt;</span><span class="identifier">unique_chars</span><span class="special">,</span> <span class="identifier">pushable</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">base_types</span><span class="special">;</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
The <code class="computeroutput"><span class="identifier">base_types</span></code> member type
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>
which must list <span class="emphasis"><em>all and only</em></span> <code class="computeroutput"><span class="keyword">public</span></code>
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
Calls</a>), and in the same order these public base classes appear in
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>
macro is not used, it is the responsibility of the programmers to maintain
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
list changes (this might significantly complicate maintenance).
</p>
<p>
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>
macro whenever possible.
</p>
<h5>
<a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h3"></a>
<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
Values (Variadic)</a>
</h5>
<p>
As shown in <a class="link" href="tutorial.html#boost_contract.tutorial.old_values" title="Old Values">Old Values</a>,
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>
variadic macro to assign old value copies. Programmers can also assign old
values without using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
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>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<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">&amp;</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>
<span class="comment">// Program old value instead of using `OLD(size())` macro.</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">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;</span> <span class="identifier">old_size</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">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>
<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>
<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">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>
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&amp;]</span> <span class="special">{</span>
<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>
<span class="special">})</span>
<span class="special">;</span>
<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>
<span class="special">}</span>
<span class="comment">/* ... */</span>
</pre>
<p>
</p>
<p>
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>
<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
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_idm45123869813440.html" title="Function copy_old">boost::contract::copy_old</a></code>
returns <code class="computeroutput"><span class="keyword">false</span></code> (because old values
are not being copied when postcondition and exception guarantees checking
is disabled at run-time, an overridden virtual function call is not checking
postconditions or exception guarantees yet, etc.). The enclosing <code class="computeroutput"><a class="link" href="../boost/contract/make_old_idm45123869837456.html" title="Function make_old">boost::contract::make_old</a></code>
copies the old value expression and creates an old value pointer. Otherwise,
<code class="computeroutput"><a class="link" href="../boost/contract/null_old.html" title="Function null_old">boost::contract::null_old</a></code>
indicates that a null old value pointer should be created.
</p>
<p>
The <code class="computeroutput"><a class="link" href="../boost/contract/make_old_idm45123869837456.html" title="Function make_old">boost::contract::make_old</a></code>
and <code class="computeroutput"><a class="link" href="../boost/contract/copy_old_idm45123869813440.html" title="Function copy_old">boost::contract::copy_old</a></code>
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
non-virtual functions (see <a class="link" href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public
Function Overrides</a>). The old value pointer returned by <code class="computeroutput"><a class="link" href="../boost/contract/make_old_idm45123869837456.html" title="Function make_old">boost::contract::make_old</a></code>
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>
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>
(see <a class="link" href="extras.html#boost_contract.extras.old_value_requirements__templates_" title="Old Value Requirements (Templates)">Old
Value Requirements</a>).
</p>
<p>
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>
macro whenever possible.
</p>
<h5>
<a name="boost_contract.extras.no_macros__and_no_variadic_macros_.h4"></a>
<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
Interface (Variadic)</a>
</h5>
<p>
Almost all macros defined in <code class="computeroutput"><a class="link" href="../reference.html#header.boost.contract_macro_hpp" title="Header &lt;boost/contract_macro.hpp&gt;">boost/contract_macro.hpp</a></code>
are variadic macros. On compilers that do not support variadic macros, programmers
can manually disable contract code compilation using <code class="computeroutput"><span class="preprocessor">#ifndef</span>
<span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code>
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
Contract Compilation</a>.
</p>
</div>
<div class="footnotes">
<br><hr style="width:100; text-align:left;margin-left: 0">
<div id="ftn.boost_contract.extras.old_value_requirements__templates_.f0" class="footnote">
<p><a href="#boost_contract.extras.old_value_requirements__templates_.f0" class="para"><sup class="para">[68] </sup></a>
<span class="bold"><strong>Rationale:</strong></span> <a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
and other proposals to add contracts to C++ do not provide a mechanism
to selectively disable copies only for old value types that are not copy
constructible. However, this library provides such a mechanism to allow
to program contracts for template code without necessarily adding extra
copy constructible type requirements that would not be present if it were
not for copying the old values (so compiling the code with and without
contracts will not necessarily alter the type requirements of the program).
Something similar could be achieved combing C++17 <code class="computeroutput"><span class="keyword">if</span>
<span class="keyword">constexpr</span></code> with <a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
or <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a> so that old value expressions
within template code could be guarded by <code class="computeroutput"><span class="keyword">if</span>
<span class="keyword">constexpr</span></code> statements checking if
the old value types are copyable or not. For example, assuming old values
are added to <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a> (using the <code class="computeroutput"><span class="identifier">oldof</span><span class="special">(...)</span></code>
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>
contracts:
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">offset</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;</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><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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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>
<span class="special">...</span>
</pre>
<p>
</p>
</div>
<div id="ftn.boost_contract.extras.assertion_requirements__templates_.f0" class="footnote">
<p><a href="#boost_contract.extras.assertion_requirements__templates_.f0" class="para"><sup class="para">[69] </sup></a>
<span class="bold"><strong>Rationale:</strong></span> <a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
and other proposals to add contracts to C++ do not provide a mechanism
to selectively disable assertions based on their type requirements. However,
this library provides such a mechanism to allow to program contracts for
template code without necessarily adding extra type requirements that would
not be present if it was not for the contracts (so compiling the code with
and without contracts will not necessarily alter the type requirements
of the program). Something similar could be achieved combing C++17 <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
with <a class="link" href="bibliography.html#N1962_anchor">[N1962]</a> or <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a>
so that contract assertions within template code could be guarded by <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
statements checking related type requirements (<a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
already supports <code class="computeroutput"><span class="keyword">if</span></code> statements
under the name of <span class="emphasis"><em>select assertions</em></span>, <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> as well).
For example, assuming old values are added to <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a>
(using the <code class="computeroutput"><span class="identifier">oldof</span><span class="special">(...)</span></code>
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>
contracts:
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">vector</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</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">&amp;</span> <span class="identifier">value</span><span class="special">)</span>
<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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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>
<span class="special">...</span>
<span class="special">};</span>
</pre>
<p>
</p>
</div>
<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">[70] </sup></a>
For optimization reasons, 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>
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>.
</p></div>
<div id="ftn.boost_contract.extras.assertion_requirements__templates_.f2" class="footnote"><p><a href="#boost_contract.extras.assertion_requirements__templates_.f2" class="para"><sup class="para">[71] </sup></a>
Boost.Hana (<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
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>
on C++14 compilers.
</p></div>
<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">[72] </sup></a>
<span class="bold"><strong>Rationale:</strong></span> Constructors and destructors
check <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
and <code class="computeroutput"><span class="keyword">const</span></code> invariants in that
order because the qualifier that can be applied to more calls is checked
first (note that <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>
calls can be made on any object while <code class="computeroutput"><span class="keyword">const</span></code>
calls cannot be made on <code class="computeroutput"><span class="keyword">volatile</span></code>
objects, in that sense the <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">volatile</span></code> qualifier can be applied
to more calls than <code class="computeroutput"><span class="keyword">const</span></code> alone
can). This is consistent with <code class="computeroutput"><span class="keyword">static</span></code>
class invariants that are checked even before <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">volatile</span></code> invariants (the <code class="computeroutput"><span class="keyword">static</span></code> classifier can be applied to even
more calls than <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code>,
in fact an object is not even needed to make static calls).
</p></div>
<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">[73] </sup></a>
<span class="bold"><strong>Rationale:</strong></span> Note that while all public
functions can be made to check <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">volatile</span></code> invariants, it is never
possible to make volatile public functions check <code class="computeroutput"><span class="keyword">const</span></code>
non-volatile invariants. That is because both <code class="computeroutput"><span class="keyword">const</span></code>
and <code class="computeroutput"><span class="keyword">volatile</span></code> can always be
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>
is always automatically added by this library in order to enforce contract
constant-correctness (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
That said, it would be too stringent for this library to also automatically
add <code class="computeroutput"><span class="keyword">volatile</span></code> and require all
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>)
invariants because only <code class="computeroutput"><span class="keyword">volatile</span></code>
members can be accessed from <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">volatile</span></code> invariants so there could
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>)
members that are accessible from <code class="computeroutput"><span class="keyword">const</span></code>
invariants but not from <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code> invariants. To avoid this confusion,
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>
<span class="keyword">volatile</span></code> invariants so that only
volatile public functions check <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">volatile</span></code> invariants and only non-volatile
public functions check <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>)
invariants. This is simple and should serve most cases. If programmers
need non-volatile public functions to also check <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">volatile</span></code> invariants, they can explicitly
do so by calling the <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span></code> invariant function from the <code class="computeroutput"><span class="keyword">const</span></code> invariant function as shown in this
documentation.
</p></div>
<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">[74] </sup></a>
In this example, the <code class="computeroutput"><span class="identifier">moved</span><span class="special">()</span></code> function is simple enough that programmers
could decide to not even call <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45123869756752.html" title="Function template public_function">boost::contract::public_function</a></code>
from it. However, calling <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45123869756752.html" title="Function template public_function">boost::contract::public_function</a></code>
from <code class="computeroutput"><span class="identifier">moved</span><span class="special">()</span></code>
has no negative impact a part from run-time overhead because this library
already automatically disables contract checking while checking other contracts
(so this call will not cause infinite recursion).
</p></div>
<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">[75] </sup></a>
The assertion levels predefined by this library are similar to the default,
audit, and axiom levels proposed in <a class="link" href="bibliography.html#P0380_anchor">[P0380]</a>.
</p></div>
<div id="ftn.boost_contract.extras.separate_body_implementation.f0" class="footnote">
<p><a href="#boost_contract.extras.separate_body_implementation.f0" class="para"><sup class="para">[76] </sup></a>
When used as default parameter values, lambda functions allow to program
code statements within function declarations. However, these lambadas cannot
be effectively used to program contracts because the C++11 standard does
not allow them to capture any variable (it would be not at all obvious
how to correctly define the semantics of such captures). For example, the
following code does not compile:
</p>
<pre class="programlisting"><span class="comment">// Specifications (in declaration).</span>
<span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span>
<span class="comment">// Error: Lambdas in default parameters cannot capture `this`, `x`, or any other variable.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span> <span class="special">()&gt;</span> <span class="identifier">pre</span> <span class="special">=</span> <span class="special">[&amp;]</span> <span class="special">{</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">());</span>
<span class="special">},</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span> <span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&amp;,</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;)&gt;</span> <span class="identifier">post</span>
<span class="special">=</span> <span class="special">[&amp;]</span> <span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">old_x</span><span class="special">)</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="number">1</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="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">);</span>
<span class="comment">// Implementation (in definition).</span>
<span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span> <span class="special">()&gt;</span> <span class="identifier">pre</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span> <span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&amp;,</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;)&gt;</span> <span class="identifier">post</span>
<span class="special">)</span> <span class="special">{</span>
<span class="keyword">int</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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="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>
<span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span><span class="identifier">pre</span><span class="special">)</span>
<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>
<span class="special">;</span>
<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>
<span class="special">}</span>
</pre>
<p>
In any case, even if the above code compiled, it would require significant
boiler-plate code to bind return and old values.
</p>
</div>
<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">[77] </sup></a>
If C++ allowed lambda functions to capture variables by constant reference
(for example using the syntax <code class="computeroutput"><span class="special">[</span><span class="keyword">const</span><span class="special">&amp;]</span>
<span class="special">{</span> <span class="special">...</span>
<span class="special">}</span></code> and <code class="computeroutput"><span class="special">[</span><span class="keyword">const</span><span class="special">&amp;</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>,
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>)
also lambdas could be used to program contract functors that fully
enforce <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>
at compile-time. Note that C++11 lambdas allow to capture variables
by value (using <code class="computeroutput"><span class="special">[=]</span> <span class="special">{</span>
<span class="special">...</span> <span class="special">}</span></code>
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>),
these value captures are <code class="computeroutput"><span class="keyword">const</span></code>
(unless the lambda is explicitly declared <code class="computeroutput"><span class="keyword">mutable</span></code>)
but they are not suitable to program postconditions and exception guarantees
using this library (because those require capturing by reference, see
<a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>
and <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
Guarantees</a>), plus they introduce a copy of the captured value
that might be too expensive in general and therefore not suitable for
preconditions either.
</p></div>
<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">[78] </sup></a>
Alternatively, on compilers that do not support C++11 lambda functions,
<a href="http://www.boost.org/doc/libs/release/libs/local_function/doc/html/index.html" target="_top">Boost.LocalFunction</a>
could be used to program the contract functors still within the function
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>).
In general, such a code is less verbose than the example shown in this
section that uses contract functions programmed outside of the original
function definitions (about 30% less lines of code) but the contract
code is hard to read. Other libraries could also be used to program
the contract functors without C++11 lambda functions (Boost.Lambda,
Boost.Fusion, etc.) but again all these techniques will result in contract
code either more verbose, or harder to read and maintain than the code
that uses C++11 lambda functions.
</p></div>
<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">[79] </sup></a>
In this example, <code class="computeroutput"><span class="identifier">bind</span></code> was
used to generate nullary functors from the contract functions. As always
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>
must be used to bind arguments by <code class="computeroutput"><span class="keyword">const</span><span class="special">&amp;</span></code> and <code class="computeroutput"><span class="special">&amp;</span></code>
respectively, plus it might be necessary to explicitly <code class="computeroutput"><span class="keyword">static_cast</span></code>
the function pointer passed to <code class="computeroutput"><span class="identifier">bind</span></code>
for overloaded functions.
</p></div>
<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">[80] </sup></a>
Compilation times of this library were measured to be comparable between
compilers that support variadic macros and compilers that do not.
</p></div>
<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">[81] </sup></a>
<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>
macro is named after <code class="computeroutput"><span class="identifier">BOOST_FUNCTION_MAX_ARGS</span></code>.
</p></div>
<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">[82] </sup></a>
<span class="bold"><strong>Rationale:</strong></span> These macros expand SFINAE-based
introspection templates that are too complex to be programmed manually
by users (that remains the case even if C++14 generic lambdas were to be
used here). On a related note, in theory using C++14 generic lambdas, the
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>
macro could be re-implemented in a way that can be expanded at function
scope, instead of class scope (but there is not really a need to do that).
</p></div>
<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">[83] </sup></a>
<span class="bold"><strong>Rationale:</strong></span> There is no need for the code
expanded by <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
to also use C++11 <code class="computeroutput"><span class="identifier">__func__</span></code>.
That is because <code class="computeroutput"><span class="identifier">__func__</span></code>
will always expand to the name of <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> of the functor used to program the contract
assertions (e.g., of the lambda function) and it will not expand to the
name of the actual function specifying the contract.
</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2008-2018 Lorenzo Caminiti<p>
Distributed under the Boost Software License, Version 1.0 (see accompanying
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>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<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>
</div>
</body>
</html>