2021-10-05 21:37:46 +02:00

2518 lines
296 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<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 1. Boost.Contract 1.0.0">
<link rel="up" href="../index.html" title="Chapter 1. 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"><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> 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, <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code><code class="computeroutput"><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
behaves like <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code><code class="computeroutput"><span class="special">&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"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code><code class="computeroutput"><span class="special">&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 to a null pointer. Therefore, <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>
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 (to avoid
run-time errors of dereferencing null pointers).
</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, for example in the contract assertions
using <code class="computeroutput"><span class="special">*</span><span class="identifier">old_x</span>
<span class="special">...</span></code> or <code class="computeroutput"><span class="identifier">old_x</span><span class="special">-&gt;...</span></code>). <a href="#ftn.boost_contract.extras.old_value_requirements__templates_.f1" class="footnote" name="boost_contract.extras.old_value_requirements__templates_.f1"><sup class="footnote">[69]</sup></a>
</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>).
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>
If programmers want to relax the copyable type requirement, they must do
so explicitly by using the <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>
type instead of using <code class="computeroutput"><span class="keyword">auto</span></code> declarations.
</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_.old_value_type_traits"></a></span><a class="link" href="extras.html#boost_contract.extras.old_value_requirements__templates_.old_value_type_traits">Old
Value Type Traits</a>
</h5>
<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.
</p>
<p>
By default, <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code><code class="computeroutput"><span class="special">&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"><a class="link" href="../boost/contract/old_value_copy.html" title="Struct template old_value_copy">boost::contract::old_value_copy</a></code><code class="computeroutput"><span class="special">&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.
</p>
<p>
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 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>
<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 copyable or not. 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), or just specialize <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code>.
For example, for a non-copyable type <code class="computeroutput"><span class="identifier">n</span></code>
the following code will work also on non-C++11 compilers (see <a href="../../../example/features/old_if_copyable.cpp" target="_top"><code class="literal">old_if_copyable.cpp</code></a>):
</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 just because of contract assertions and to simply
skip 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"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
on C++17 compilers, and <code class="computeroutput"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code>
(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>)
on non-C++17 compilers.
</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 guard this postcondition using C++17 <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></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 skip it otherwise. <a href="#ftn.boost_contract.extras.assertion_requirements__templates_.f0" class="footnote" name="boost_contract.extras.assertion_requirements__templates_.f0"><sup class="footnote">[70]</sup></a> For example:
</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">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>
More in general, <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
can be used to guard a mix of both old value copies and contract assertions
that introduce specific extra type requirements. For example, the following
<code class="computeroutput"><span class="identifier">swap</span></code> function can be called
on any type <code class="computeroutput"><span class="identifier">T</span></code> that is movable
but its old value copies and postcondition assertions are evaluated only
for types <code class="computeroutput"><span class="identifier">T</span></code> that are also
copyable and have an equality operator <code class="computeroutput"><span class="special">==</span></code>
(see <a href="../../../example/features/if_constexpr.cpp" target="_top"><code class="literal">if_constexpr.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">void</span> <span class="identifier">swap</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="identifier">T</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">constexpr</span> <span class="keyword">bool</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">is_old_value_copyable</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span> <span class="special">&amp;&amp;</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</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> <span class="identifier">old_x</span><span class="special">,</span> <span class="identifier">old_y</span><span class="special">;</span>
<span class="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Contract requires copyable T...</span>
<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">old_y</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span>
<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="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// ... and T with `==`...</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_y</span><span class="special">);</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">})</span>
<span class="special">;</span>
<span class="identifier">T</span> <span class="identifier">t</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// ...but body only requires movable T.</span>
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span>
<span class="identifier">y</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">t</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
</p>
<h5>
<a name="boost_contract.extras.assertion_requirements__templates_.h0"></a>
<span class="phrase"><a name="boost_contract.extras.assertion_requirements__templates_.no__code__phrase_role__keyword__if__phrase___phrase_role__keyword__constexpr__phrase___code___no_c__17_"></a></span><a class="link" href="extras.html#boost_contract.extras.assertion_requirements__templates_.no__code__phrase_role__keyword__if__phrase___phrase_role__keyword__constexpr__phrase___code___no_c__17_">No
<code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
(no C++17)</a>
</h5>
<p>
On non-C++17 compilers where <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code> is not available, it is possible
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>
to skip assertions based on type requirements (even if this code is less
readable and more verbose than using <code class="computeroutput"><span class="keyword">if</span>
<span class="keyword">constexpr</span></code>). For example (see <a href="../../../example/features/condition_if.cpp" target="_top"><code class="literal">condition_if.cpp</code></a>):
</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">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>
<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"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></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"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></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>
(when used this way, functor templates like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal_to</span></code>
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"><a class="link" href="../boost/contract/condition_if.html" title="Function template condition_if">boost::contract::condition_if</a></code><code class="computeroutput"><span class="special">&lt;</span><span class="identifier">Pred</span><span class="special">&gt;(</span><span class="identifier">cond</span><span class="special">)</span></code> is logically equivalent to <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code><code class="computeroutput"><span class="special">&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">[71]</sup></a> The <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>
function template also 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 (including
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 functor template instantiations (not just 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>
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). 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>
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).
<a href="#ftn.boost_contract.extras.assertion_requirements__templates_.f2" class="footnote" name="boost_contract.extras.assertion_requirements__templates_.f2"><sup class="footnote">[72]</sup></a>
</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_idm45028039722128.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">[73]</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">[74]</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">auto</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">*</span> <span class="identifier">cv</span> <span class="special">=</span> <span class="keyword">this</span><span class="special">;</span> <span class="identifier">cv</span><span class="special">-&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, at a minimum 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 any other reason,
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_idm45028038882752.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="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">[75]</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_idm45028038882752.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 avoid the run-time overhead of checking contract
assertions and to maximize performance (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.benefits_and_costs" title="Benefits and Costs">Benefits
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>
A C++ <code class="computeroutput"><span class="keyword">union</span></code> cannot have virtual
functions, base 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), instead <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
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 (as usual).</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 (as usual).</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="identifier">d_</span><span class="special">(</span><span class="number">0</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="special">{</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">;</span> <span class="identifier">get</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
<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="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="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">[76]</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 the ones we have seen so far, they are always checked at run-time
and they cannot be disabled.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028040814800.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 asserted conditions are always compiled
and therefore 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_idm45028067443360.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 therefore validated syntactically (so these assertions
can serve as formal comments to 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_idm45028040814800.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028067443360.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_idm45028040814800.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_idm45028067443360.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 these assertion levels that are 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">EXPONENTIALLY_COMPLEX_ASSERTIONS</span>
<span class="comment">// Following will compile and also evaluate `cond`.</span>
<span class="preprocessor">#define</span> <span class="identifier">ASSERT_EXP</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</span>
<span class="preprocessor">#else</span>
<span class="comment">// Following will compile but never actually evaluate `cond`.</span>
<span class="preprocessor">#define</span> <span class="identifier">ASSERT_EXP</span><span class="special">(</span><span class="identifier">cond</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="keyword">true</span> <span class="special">||</span> <span class="special">(</span><span class="identifier">cond</span><span class="special">))</span>
<span class="preprocessor">#endif</span>
<span class="special">...</span>
<span class="identifier">ASSERT_EXP</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>some-exponentially-complex-boolean-condition</em></span></code><span class="special">);</span>
</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 groups
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_idm45028039660048.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_idm45028039653664.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_idm45028039634896.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_idm45028039627280.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_idm45028039619664.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 defining both <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039634896.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_idm45028039627280.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 evaluate 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_idm45028039653664.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 overheads 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_idm45028039653664.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_idm45028039627280.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> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</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_idm45028039603040.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_idm45028039592176.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_idm45028039583904.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_idm45028039574704.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 compile-time
errors). Instead, these macros are automatically defined by this library
when programmers define <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039660048.html" title="Macro BOOST_CONTRACT_NO_PRECONDITIONS">BOOST_CONTRACT_NO_PRECONDITIONS</a></code>,
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039653664.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_idm45028039619664.html" title="Macro BOOST_CONTRACT_NO_INVARIANTS">BOOST_CONTRACT_NO_INVARIANTS</a></code>
(or <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039634896.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_idm45028039627280.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 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>
that can also be used to completely disable compile-time and run-time overheads
introduced by contracts but without the burden of manually writing the <code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> statements. For example, the following
code shows how to use both the <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>
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 overheads 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_idm45028038671712.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>).
</p>
<p>
For constructors, destructors, and public functions the <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>
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 can be used as follow (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_idm45028038619104.html" title="Macro BOOST_CONTRACT_STATIC_INVARIANT">BOOST_CONTRACT_STATIC_INVARIANT</a></code>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028038632960.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 <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>
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 this 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 still 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 or run-time overhead (specifically, extra <code class="computeroutput"><a class="link" href="../boost/contract/virtual_.html" title="Class virtual_">boost::contract::virtual_</a></code><code class="computeroutput"><span class="special">*</span></code> parameters, calls to <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
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 unless
<code class="computeroutput"><span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_CONTRACT_NO_</span><span class="special">...</span></code> statements are used).
</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
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 <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>
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 tool 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> (here named <code class="computeroutput"><span class="special">...</span><span class="identifier">_body</span></code>, but any other naming scheme could
be used) that are compiled in object files. Function definitions that remain
in header files instead will contain just contract code followed by calls
to the extra body functions. This technique allows to keep the contract code
in header files while separating the implementation code to source and object
files. However, this adds the overhead of manually programming an extra function
declaration for each 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">[77]</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, and protected 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_idm45028039653664.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_idm45028039627280.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). <a href="#ftn.boost_contract.extras.no_lambda_functions__no_c__11_.f0" class="footnote" name="boost_contract.extras.no_lambda_functions__no_c__11_.f0"><sup class="footnote">[78]</sup></a>
</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_.f1" class="footnote" name="boost_contract.extras.no_lambda_functions__no_c__11_.f1"><sup class="footnote">[79]</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>).
</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, the header file (see <a href="../../../example/features/no_lambdas.hpp" target="_top"><code class="literal">no_lambdas.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">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>
And, the source file (see <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="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">
For constructors: 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">
For destructors: 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">[80]</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 (because of the large amount of boiler-plate code required
when C++11 lambdas are not used as also shown by the example above).
</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_idm45028038910320.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">[81]</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_idm45028038910320.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">[82]</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">[83]</sup></a> The <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDES.html" title="Macro BOOST_CONTRACT_OVERRIDES">BOOST_CONTRACT_OVERRIDES</a></code>
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></code><code class="literal"><span class="emphasis"><em>cond</em></span></code><code class="computeroutput"><span class="special">)</span></code> simply expands to code equivalent to the
following: <a href="#ftn.boost_contract.extras.no_macros__and_no_variadic_macros_.f3" class="footnote" name="boost_contract.extras.no_macros__and_no_variadic_macros_.f3"><sup class="footnote">[84]</sup></a>
</p>
<pre class="programlisting"><span class="keyword">if</span><span class="special">(!(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">))</span> <span class="special">{</span>
<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><code class="literal"><span class="emphasis"><em>cond</em></span></code><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><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span> <span class="keyword">throw</span> <code class="literal"><span class="emphasis"><em>exception-object</em></span></code><span class="special">;</span>
</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>
As shown in <a class="link" href="extras.html#boost_contract.extras.assertion_levels" title="Assertion Levels">Assertion
Levels</a>, this library pre-defines <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028040814800.html" title="Macro BOOST_CONTRACT_ASSERT_AUDIT">BOOST_CONTRACT_ASSERT_AUDIT</a></code>
and <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028067443360.html" title="Macro BOOST_CONTRACT_ASSERT_AXIOM">BOOST_CONTRACT_ASSERT_AXIOM</a></code>
assertion levels. These macros are not variadic macros and programmers should
be able to use them on all C++ compilers. In any case, 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><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span> <span class="special">\</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span>
<span class="preprocessor">#else</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTRACT_ASSERT_AUDIT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span> <span class="special">\</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="keyword">true</span> <span class="special">||</span> <span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">))</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTRACT_ASSERT_AXIOM</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">)</span> <span class="special">\</span>
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="keyword">true</span> <span class="special">||</span> <span class="special">(</span><code class="literal"><span class="emphasis"><em>cond</em></span></code><span class="special">))</span>
</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_idm45028038942304.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 guarantee 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_idm45028038966352.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_idm45028038966352.html" title="Function make_old">boost::contract::make_old</a></code>
and <code class="computeroutput"><a class="link" href="../boost/contract/copy_old_idm45028038942304.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_idm45028038966352.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 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 can 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 some kind
of <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.old_value_requirements__templates_.f1" class="footnote">
<p><a href="#boost_contract.extras.old_value_requirements__templates_.f1" class="para"><sup class="para">[69] </sup></a>
Technically, on C++17 it is possible to use <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code>
together with <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span></code>
instead of using <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>,
for example:
</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">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> <span class="identifier">old_x</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">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><span class="special">)</span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
<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="keyword">if</span> <span class="keyword">constexpr</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">is_old_value_copyable</span><span class="special">&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">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>
However, the authors find this code less readable and more verbose than
its equivalent that uses <code class="computeroutput"><a class="link" href="../boost/contract/old_ptr_if_copyable.html" title="Class template old_ptr_if_copyable">boost::contract::old_ptr_if_copyable</a></code>.
Guarding old value copies and related assertions with <code class="computeroutput"><span class="keyword">if</span>
<span class="keyword">constexpr</span></code> is useful instead when
the guard condition checks type requirements more complex than just <code class="computeroutput"><a class="link" href="../boost/contract/is_old_value_copyable.html" title="Struct template is_old_value_copyable">boost::contract::is_old_value_copyable</a></code>
(as shown later in this documentation).
</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">[70] </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 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 the
related type requirements (<a class="link" href="bibliography.html#N1962_anchor">[N1962]</a>
already allows of <code class="computeroutput"><span class="keyword">if</span></code> statements
in contracts 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 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">[71] </sup></a>
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>
is optimized and it does not actually use <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>.
</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">[72] </sup></a>
</p>
<p>
A part from its use within contracts, <code class="computeroutput"><a class="link" href="../boost/contract/call_if.html" title="Function template call_if">boost::contract::call_if</a></code>
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>
(<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). For example, the following implementation of <code class="computeroutput"><span class="identifier">myadvance</span></code> will compile since C++14
and it 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 (see
<a href="../../../example/features/call_if_cxx14.cpp" target="_top"><code class="literal">call_if_cxx14.cpp</code></a>):
</p>
<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">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>
<p>
</p>
<p>
Of course, since C++17 the implementation that uses <code class="computeroutput"><span class="keyword">if</span>
<span class="keyword">constexpr</span></code> is even more readable
and concise:
</p>
<pre class="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">i</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>
<p>
</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">[73] </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">[74] </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 a clear distinction and it 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">[75] </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_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
from it for optimization reasons. However, calling <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.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
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">[76] </sup></a>
The assertion levels predefined by this library are similar to the default,
audit, and axiom levels from <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">[77] </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 in function declarations instead
of definitions. That is because the C++11 standard does not allow lambdas
in function declarations to capture any variable (for the good reason that
it is not at all obvious how to correctly define the semantics of such
captures). For example, the following code is not valid C++ and it 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">[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_.f1" class="footnote"><p><a href="#boost_contract.extras.no_lambda_functions__no_c__11_.f1" class="para"><sup class="para">[79] </sup></a>
If C++ allowed lambda functions to capture variables by constant reference
(for example allowing a syntax like this <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>)
and 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_.f2" class="footnote"><p><a href="#boost_contract.extras.no_lambda_functions__no_c__11_.f2" class="para"><sup class="para">[80] </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">[81] </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">[82] </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">[83] </sup></a>
<span class="bold"><strong>Rationale:</strong></span> These macros expand to SFINAE-based
introspection template code 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">[84] </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 <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> of the functor used to program the contract
assertions (e.g., the internal name the compiler assigns to lambda functions)
and it will not expand to the name of the actual function enclosing the
contract declaration.
</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 © 2008-2019 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>