Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / contract / doc / extras.qbk
1
2 [/ Copyright (C) 2008-2018 Lorenzo Caminiti]
3 [/ Distributed under the Boost Software License, Version 1.0 (see accompanying]
4 [/ file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).]
5 [/ See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html]
6
7 [section Extras]
8
9 This section can be consulted selectively for specific topics of interest.
10
11 [section Old Value Requirements (Templates)]
12
13 Old values require to copy the expression passed to [macroref BOOST_CONTRACT_OLDOF] thus the type of that expression needs to be copyable.
14 More precisely, dereferencing an old value pointer of type [classref boost::contract::old_ptr]`<T>` requires [classref boost::contract::is_old_value_copyable]`<T>::value` to be `true`, otherwise this library will generate a compile-time error.
15
16 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).
17 In these cases, programmers can declare old values using [classref boost::contract::old_ptr] as seen so far.
18
19 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.
20 Programmers can do this using [classref boost::contract::old_ptr_if_copyable] instead of [classref boost::contract::old_ptr] and checking if the old value pointer is not null before dereferencing it in postconditions.
21 For example, consider the following function template that could in general be instantiated for types `T` that are not copy constructible (that is for which [classref boost::contract::is_old_value_copyable]`<T>::value` is `false`, see [@../../example/features/old_if_copyable.cpp =old_if_copyable.cpp=]):
22 [footnote
23 *Rationale:*
24 __N1962__ 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.
25 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).
26 Something similar could be achieved combing C++17 `if constexpr` with __N1962__ or __P0380__ so that old value expressions within template code can be guarded by `if constexpr` statements checking if the old value types are copyable or not.
27 For example, assuming old values are added to __P0380__ (using some kind of `oldof(...)` syntax) and that C++17 `if constexpr` can be used within __P0380__ contracts:
28 ``
29     template<typename T>
30     void offset(T& x, int count)
31         [[ensures: if constexpr(std::is_copy_constructible<T>::value) x == oldof(x) + count]]
32     ...
33 ``
34 ]
35
36 [import ../example/features/old_if_copyable.cpp]
37 [old_if_copyable_offset]
38
39 The old value pointer `old_x` is programmed using [classref boost::contract::old_ptr_if_copyable].
40 When `T` is copyable, [classref boost::contract::old_ptr_if_copyable]`<T>` behaves like [classref boost::contract::old_ptr]`<T>`.
41 When `T` is not copyable instead, [classref boost::contract::old_ptr_if_copyable]`<T>` will simply not copy `x` at run-time and leave `old_x` initialized to a null pointer.
42 Therefore, [classref boost::contract::old_ptr_if_copyable] objects like `old_x` must be checked to be not null as in `if(old_x) ...` before they are dereferenced in postconditions and exception guarantees (to avoid run-time errors of dereferencing null pointers).
43
44 If the above example used [classref boost::contract::old_ptr] instead then this library would have generated a compile-time error when `offset` is instantiated with types `T` that are not copy constructible (but only if `old_x` is actually dereferenced somewhere, for example in the contract assertions using `*old_x ...` or `old_x->...`).
45 [footnote
46 Technically, on C++17 it is possible to use [classref boost::contract::old_ptr] together with `if constexpr` instead of using [classref boost::contract::old_ptr_if_copyable], for example:
47 ``
48     template<typename T>
49     void offset(T& x, int count) {
50         boost::contract::old_ptr<T> old_x;
51         if constexpr(boost::contract::is_old_value_copyable<T>::value) old_x = BOOST_CONTRACT_OLDOF(x);
52         boost::contract::check c = boost::contract::function()
53             .postcondition([&] {
54                 if constexpr(boost::contract::is_old_value_copyable<T>::value) BOOST_CONTRACT_ASSERT(x == *old_x + count);
55             })
56         ;
57
58         x += count;
59     }
60 ``
61 However, the authors find this code less readable and more verbose than its equivalent that uses [classref boost::contract::old_ptr_if_copyable].
62 Guarding old value copies and related assertions with `if constexpr` is useful instead when the guard condition checks type requirements more complex than just [classref boost::contract::is_old_value_copyable] (as shown later in this documentation).
63 ]
64
65 When C++11 `auto` declarations are used with [macroref BOOST_CONTRACT_OLDOF], this library always defaults to using the [classref boost::contract::old_ptr] type (because its type requirements are more stringent than [classref boost::contract::old_ptr_if_copyable]).
66 For example, the following statements are equivalent:
67
68     auto old_x = BOOST_CONTRACT_OLDOF(x); // C++11 auto declarations always use `old_ptr` (never `old_ptr_if_copyable`).
69     boost::contract::old_ptr<decltype(x)> old_x = BOOST_CONTRACT_OLDOF(x);
70
71 If programmers want to relax the copyable type requirement, they must do so explicitly by using the [classref boost::contract::old_ptr_if_copyable] type instead of using `auto` declarations.
72
73 [heading Old Value Type Traits]
74
75 This library uses [classref boost::contract::is_old_value_copyable] to determine if an old value type is copyable or not, and then [classref boost::contract::old_value_copy] to actually copy the old value.
76
77 By default, [classref boost::contract::is_old_value_copyable]`<T>` is equivalent to `boost::is_copy_constructible<T>` and [classref boost::contract::old_value_copy]`<T>` is implemented using `T`'s copy constructor.
78 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.
79
80 For example, the following specialization of [classref boost::contract::is_old_value_copyable] intentionally avoids making old value copies for all expressions of type `w` even if that type has a copy constructor (see [@../../example/features/old_if_copyable.cpp =old_if_copyable.cpp=]):
81
82 [old_if_copyable_w_decl]
83 [old_if_copyable_w_spec]
84
85 On the flip side, the following specializations of [classref boost::contract::is_old_value_copyable] and [classref boost::contract::old_value_copy] make old value copies of expressions of type `p` even if that type does not actually have a copy constructor (see [@../../example/features/old_if_copyable.cpp =old_if_copyable.cpp=]):
86
87 [old_if_copyable_p_decl]
88 [old_if_copyable_p_spec]
89
90 In general, `boost::is_copy_constructible` and therefore [classref boost::contract::is_old_value_copyable] require C++11 `decltype` and SFINAE to automatically detect if a given type is copyable or not.
91 On non-C++11 compilers, it is possible to inherit the old value type from `boost::noncopyable`, or use `BOOST_MOVABLE_BUT_NOT_COPYABLE`, or specialize `boost::is_copy_constructible` (see [@http://www.boost.org/doc/libs/release/libs/type_traits/doc/html/boost_typetraits/reference/is_copy_constructible.html `boost::is_copy_constructible`] documentation for more information), or just specialize [classref boost::contract::is_old_value_copyable].
92 For example, for a non-copyable type `n` the following code will work also on non-C++11 compilers (see [@../../example/features/old_if_copyable.cpp =old_if_copyable.cpp=]):
93
94 [old_if_copyable_n_decl]
95 [old_if_copyable_n_spec]
96
97 [endsect]
98
99 [section Assertion Requirements (Templates)]
100
101 In general, assertions can introduce a new set of requirements on the types used by the program.
102 Some of these type requirements might be necessary only to check the assertions and they would not be required by the program otherwise.
103
104 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).
105 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.
106
107 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.
108 Programmers can do this using `if constexpr` on C++17 compilers, and [funcref boost::contract::condition_if] (or [funcref boost::contract::condition_if_c]) on non-C++17 compilers.
109
110 For example, let's consider the following `vector<T>` class template equivalent to `std::vector<T>`.
111 C++ `std::vector<T>` does not require that its value type parameter `T` has an equality operator `==` (it only requires `T` to be copy constructible, see `std::vector` documentation).
112 However, the contracts for the `vector<T>::push_back(value)` public function include a postcondition `back() == value` that introduces the new requirement that `T` must also have an equality operator `==`.
113 Programmers can specify this postcondition as usual with `BOOST_CONTRACT_ASSERT(back() == value)` an let the program fail to compile when users instantiate `vector<T>` with a type `T` that does not provide an equality operator `==`.
114 Otherwise, programmers can guard this postcondition using C++17 `if constexpr` to evaluate the asserted condition only for types `T` that have an equality operator `==` and skip it otherwise.
115 [footnote
116 *Rationale:*
117 __N1962__ and other proposals to add contracts to C++ do not provide a mechanism to selectively disable assertions based on their type requirements.
118 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).
119 Something similar could be achieved combing C++17 `if constexpr` with __N1962__ or __P0380__ so that contract assertions within template code could be guarded by `if constexpr` statements checking the related type requirements (__N1962__ already allows of `if` statements in contracts under the name of /select assertions/, __P0380__ does not so probably `if` statements should be added to __P0380__ as well).
120 For example, assuming C++17 `if constexpr` can be used within __P0380__ contracts:
121 ``
122     template<typename T>
123     class vector {
124     public:
125         void push_back(T const& value)
126             [[ensures: if constexpr(boost::has_equal_to<T>::value) back() == value]]
127         ...
128     };
129 ``
130 ]
131 For example:
132
133     template<typename T>
134     class vector {
135     public:
136         void push_back(T const& value) {
137             boost::contract::check c = boot::contract::public_function(this)
138                 .postcondition([&] {
139                     // Guard with `if constexpr` for T without `==`.
140                     if constexpr(boost::has_equal_to<T>::value)
141                         BOOST_CONTRACT_ASSERT(back() == value);
142                 })
143             ;
144
145             vect_.push_back(value);
146         }
147
148         /* ... */
149
150 More in general, `if constexpr` can be used to guard a mix of both old value copies and contract assertions that introduce specific extra type requirements.
151 For example, the following `swap` function can be called on any type `T` that is movable but its old value copies and postcondition assertions are evaluated only for types `T` that are also copyable and have an equality operator `==` (see [@../../example/features/if_constexpr.cpp =if_constexpr.cpp=]):
152
153 [import ../example/features/if_constexpr.cpp]
154 [if_constexpr]
155
156 [heading No `if constexpr` (no C++17)]
157
158 On non-C++17 compilers where `if constexpr` is not available, it is possible to use [funcref boost::contract::condition_if] to skip assertions based on type requirements (even if this code is less readable and more verbose than using `if constexpr`).
159 For example (see [@../../example/features/condition_if.cpp =condition_if.cpp=]):
160
161 [import ../example/features/condition_if.cpp]
162 [condition_if]
163
164 More in general, [funcref boost::contract::condition_if] is used as follow:
165
166     boost::contract::condition_if<Pred>(
167         cond
168     )
169
170 Where `Pred` is a nullary boolean meta-function and `cond` is a nullary boolean functor.
171 If `Pred::value` is statically evaluated to be `true` at compile-time then `cond()` is called at run-time and its boolean result is returned by the enclosing [funcref boost::contract::condition_if] call.
172 Otherwise, if `Pred::value` is statically evaluated to be `false` at compile-time then [funcref boost::contract::condition_if] trivially returns `true`.
173 Therefore, if `cond` 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 `==`) will not be actually instantiated and compiled unless the compiler determines at compile-time that `Pred::value` is `true` (when used this way, functor templates like `std::equal_to` and C++14 generic lambdas can be used to program `cond`, but C++11 lambdas cannot).
174
175 The [funcref boost::contract::condition_if] function template is a special case of the more general [funcref boost::contract::call_if], specifically [funcref boost::contract::condition_if]`<Pred>(cond)` is logically equivalent to [funcref boost::contract::call_if]`<Pred>(cond).else_([] { return true; })`.
176 [footnote
177 The internal implementation of [funcref boost::contract::condition_if] is optimized and it does not actually use [funcref boost::contract::call_if].
178 ]
179 The [funcref boost::contract::call_if] function template also accepts a number of optional /else-if/ statements and one optional /else/ statement:
180
181     boost::contract::call_if<Pred1>(
182         t1
183     ).template else_if<Pred2>(          // Optional.
184         t2
185     )
186     ...                                 // Optionally, other `else_if` statements.
187     .else_(                             // Optional for `void` functors, otherwise required.
188         e
189     )
190
191 Where `Pred1`, `Pred2`, ... are nullary boolean meta-functions and `t1`, `t2`, ..., `e` are nullary functors.
192 The return types of the functor calls `t1()`, `t2()`, ..., `e()` must either be all the same (including possibly all `void`) or be of types implicitly convertible into one another.
193 At run-time [funcref boost::contract::call_if] will call the functor `t1()`, or `t2()`, ..., or `e()` depending on which meta-function `Pred1::value`, `Pred2::value`, ... is statically evaluated to be `true` or `false` at compile-time, and it will return the value returned by the functor being called. 
194 If `t1`, `t2`, ..., `e` 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 `Pred1::value`, `Pred2::value`, ... are respectively evaluated to be `true` or `false` at compile-time).
195 All the `else_if<...>(...)` statements are optional.
196 The `else_(...)` statement is optional if the functor calls return `void`, otherwise it is required.
197
198 In general, [funcref boost::contract::call_if] can be used to program contract assertions that compile and check different functor templates depending on related predicates being statically evaluated to be `true` or `false` at compile-time (but in most cases [funcref boost::contract::condition_if] should be sufficient and less verbose to use).
199 The [funcref boost::contract::condition_if_c], [funcref boost::contract::call_if_c], and `.else_if_c` function templates work similarly to their counterparts without the `..._c` postfix seen so far, but they take their predicate template parameters as static boolean values instead of nullary boolean meta-functions.
200
201 [import ../example/features/call_if_cxx14.cpp]
202 On compilers that support C++17 `if constexpr` there should be no need to use [funcref boost::contract::condition_if] or [funcref boost::contract::call_if] because `if constexpr` can be used instead (making the code more readable and easier to program).
203 [footnote
204 A part from its use within contracts, [funcref boost::contract::call_if] can be used together with C++14 generic lambdas to emulate C++17 `if constexpr` (`boost::hana::if_` and probably other approaches can also be used together with generic lambdas to emulate C++17 `if constexpr` on C++14 compilers).
205 For example, the following implementation of `myadvance` will compile since C++14 and it is more concise, easier to read and maintain than the usual implementation of `std::advance` that uses tag dispatching (see [@../../example/features/call_if_cxx14.cpp =call_if_cxx14.cpp=]):
206 [call_if_cxx14]
207 Of course, since C++17 the implementation that uses `if constexpr` is even more readable and concise:
208 ``
209 template<typename Iter, typename Dist>
210 void myadvance(Iter& i, Dist n) {
211     if constexpr(is_random_access_iterator<Iter>::value) {
212         i += n;
213     } else if constexpr(is_bidirectional_iterator<Iter>::value) {
214         if(n >= 0) while(n--) ++i;
215         else while(n++) --i;
216     } else if constexpr(is_input_iterator<Iter>::value) {
217         while(n--) ++i;
218     } else {
219         static_assert(false, "requires at least input iterator");
220     }
221 }
222 ``
223 ]
224
225 [endsect]
226
227 [section Volatile Public Functions]
228
229 This library allows to specify a different set of class invariants to check for volatile public functions.
230 These /volatile class invariants/ are programmed in a public `const volatile` function, named `invariant`, taking no argument, and returning `void` (see [macroref BOOST_CONTRACT_INVARIANT_FUNC] to name the invariant function differently from `invariant` and __Access_Specifiers__ to not have to declare it `public`).
231 Classes that do no have invariants for their volatile public functions, simply do not declare the `void invariant() const volatile` function.
232
233 In general, `const volatile` invariants work the same as `const` invariants (see __Class_Invariants__) with the only difference that `volatile` and `const volatile` functions check `const volatile` invariants while non-`const` (i.e., neither `const` nor `volatile`) and `const` functions check `const` invariants.
234 A given class can specify any combination of `static`, `const volatile`, and `const` invariant functions (see __Class_Invariants__):
235 [footnote
236 *Rationale:*
237 Constructors and destructors check `const volatile` and `const` invariants in that order because the qualifier that can be applied to more calls is checked first (note that `const volatile` calls can be made on any object while `const` calls cannot be made on `volatile` objects, in that sense the `const volatile` qualifier can be applied to more calls than `const` alone can).
238 This is consistent with `static` class invariants that are checked even before `const volatile` invariants (the `static` classifier can be applied to even more calls than `const volatile`, in fact an object is not even needed to make static calls).
239 ]
240
241 * Constructors check `static` invariants at entry and exit (even if an exception is thrown), plus `const volatile` and `const` invariants in that order at exit but only if no exception is thrown.
242 * Destructors check `static` invariants at entry and exit (even if an exception is thrown), plus `const volatile` and `const` 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++).
243 * Both non-`const` and `const` public functions check `static` and `const` invariants at entry and at exit (even if an exception is thrown).
244 * Both `volatile` and `const volatile` public functions check `static` and `const volatile` invariants at entry and at exit (even if an exception is thrown).
245
246 These rules ensure that volatile class invariants are correctly checked (see __Constructor_Calls__, __Destructor_Calls__, and __Public_Function_Calls__).
247 For example (see [@../../example/features/volatile.cpp =volatile.cpp=]):
248
249 [import ../example/features/volatile.cpp]
250 [volatile]
251
252 This library does not automatically check `const volatile` invariants for non-`volatile` functions.
253 However, if the contract specifications require it, programmers can explicitly call the `const volatile` invariant function from the `const` invariant function (preferably in that order to be consistent with the order `const volatile` and `const` invariants are checked for constructors and destructors).
254 That way all public functions, `volatile` or not, will check `const volatile` invariants (while only `const` and non-`const` public functions will check only `const` invariants, correctly so because the `volatile` qualifier shall not be stripped away):
255 [footnote
256 *Rationale:*
257 Note that while all public functions can be made to check `const volatile` invariants, it is never possible to make volatile public functions check `const` non-volatile invariants.
258 That is because both `const` and `volatile` can always be added but never stripped in C++ (a part from forcefully via `const_cast`) but `const` is always automatically added by this library in order to enforce contract constant-correctness (see __Constant_Correctness__).
259 That said, it would be too stringent for this library to also automatically add `volatile` and require all functions to check `const volatile` (not just `const`) invariants because only `volatile` members can be accessed from `const volatile` invariants so there could be many `const` (but not `const volatile`) members that are accessible from `const` invariants but not from `const volatile` invariants.
260 To avoid this confusion, this library has chosen to draw a clear dichotomy between `const` and `const volatile` invariants so that only volatile public functions check `const volatile` invariants and only non-volatile public functions check `const` (but not `const volatile`) invariants.
261 This is a clear distinction and it should serve most cases.
262 If programmers need non-volatile public functions to also check `const volatile` invariants, they can explicitly do so by calling the `const volatile` invariant function from the `const` invariant function as shown in this documentation.
263 ]
264
265     class u {
266     public:
267         void invariant() const volatile { ... }                 // Volatile invariants.
268
269         void invariant() const {
270             auto const volatile* cv = this; cv->invariant();    // Call `const volatile` invariant function above.
271             ...                                                 // Other non-volatile invariants.
272         }
273
274         ...
275     };
276
277 (As usual, private and protected functions do not check any invariant, not even when they are `volatile` or `const volatile`, see __Private_and_Protected_Functions__).
278
279 [endsect]
280
281 [section Move Operations]
282
283 As with all public operations of a class, also public move operations should maintain class invariants (see __Stroustrup13__, p. 520).
284 Specifically, at a minimum C++ requires the following:
285
286 * The moved-from object can be copy assigned.
287 * The moved-from object can be move assigned.
288 * 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 __Destructor_Calls__).
289
290 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 [funcref boost::contract::constructor] and [funcref boost::contract::public_function] as usual.
291 For example (see [@../../example/features/move.cpp =move.cpp=]):
292
293 [import ../example/features/move.cpp]
294 [move]
295
296 This example assumes that it is possible to call the public function `moved()` on the moved-from object.
297 [footnote
298 In this example, the `moved()` function is simple enough that programmers could decide to not even call [funcref boost::contract::public_function] from it for optimization reasons.
299 However, calling [funcref boost::contract::public_function] from `moved()` 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).
300 ]
301
302 [note
303 The default move constructor and move assignment operator generated by C++ will not automatically check contracts.
304 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 [funcref boost::contract::constructor], [classref boost::contract::constructor_precondition], and [funcref boost::contract::public_function] instead of relying on their default implementations generated by C++.
305 (Same as for all other operations automatically implemented by C++.)
306 ]
307
308 As always, programmers can decide to not program contracts for a given type.
309 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 __Benefits_and_Costs__).
310
311 [endsect]
312
313 [section Unions]
314
315 A C++ `union` cannot have virtual functions, base classes, and cannot be used as a base class thus subcontracting ([classref boost::contract::virtual_], [macroref BOOST_CONTRACT_OVERRIDE], etc.) do not apply to unions.
316 Also a `union` cannot inherit from [classref boost::contract::constructor_precondition] (because it cannot have base classes), instead [classref boost::contract::constructor_precondition] 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 `pre` in the example below).
317 A part from that, this library is used as usual to program contracts for unions.
318 For example (see [@../../example/features/union.cpp =union.cpp=]):
319
320 [import ../example/features/union.cpp]
321 [union]
322
323 [endsect]
324
325 [section Assertion Levels]
326
327 This library provides three predefined /assertion levels/ that can be used to selectively disable assertions depending on their computational complexity:
328 [footnote
329 The assertion levels predefined by this library are similar to the default, audit, and axiom levels from __P0380__.
330 ]
331
332 * [macroref BOOST_CONTRACT_ASSERT] is used to assert conditions that are not computationally expensive, at least compared to the cost of executing the function body.
333 These assertions are the ones we have seen so far, they are always checked at run-time and they cannot be disabled.
334 * [macroref BOOST_CONTRACT_ASSERT_AUDIT] is used to assert conditions that are computationally expensive compared to the cost of executing the function body.
335 These assertions are not checked at run-time unless programmers explicitly define [macroref BOOST_CONTRACT_AUDITS] (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).
336 * [macroref BOOST_CONTRACT_ASSERT_AXIOM] is used to assert conditions that are computationally prohibitive, at least compared to the cost of executing the function body.
337 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).
338
339 In addition, [macroref BOOST_CONTRACT_CHECK_AUDIT] and [macroref BOOST_CONTRACT_CHECK_AXIOM] are similar to [macroref BOOST_CONTRACT_ASSERT_AUDIT] and [macroref BOOST_CONTRACT_ASSERT_AXIOM] but they are used to program audit and axiom levels for implementation checks instead of assertions (see __Implementation_Checks__).
340
341 For example, [macroref BOOST_CONTRACT_ASSERT_AUDIT] can be used to program computationally expensive assertions (see [@../../example/features/assertion_level.cpp =assertion_level.cpp=]):
342
343 [import ../example/features/assertion_level.cpp]
344 [assertion_level_audit]
345
346 Similarly, [macroref BOOST_CONTRACT_AUDITS] can be used to disable expensive old value copies and related assertions that use them (see [@../../example/features/assertion_level.cpp =assertion_level.cpp=]):
347
348 [assertion_level_class_begin]
349 [assertion_level_audit_old]
350 [assertion_level_class_end]
351
352 The condition passed to [macroref BOOST_CONTRACT_ASSERT_AXIOM] 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.
353 For example, (see [@../../example/features/assertion_level.cpp =assertion_level.cpp=]):
354
355 [assertion_level_no_impl]
356 [assertion_level_class_begin]
357 [assertion_level_axiom]
358 [assertion_level_class_end]
359
360 In addition to these assertion levels that are predefined by this library, programmers are free to define their own.
361 For example, the following macro could be used to program and selectively disable assertions that have exponential computational complexity `O(e^n)`:
362
363     #ifdef EXPONENTIALLY_COMPLEX_ASSERTIONS
364         // Following will compile and also evaluate `cond`.
365         #define ASSERT_EXP(cond) BOOST_CONTRACT_ASSERT(cond)
366     #else
367         // Following will compile but never actually evaluate `cond`.
368         #define ASSERT_EXP(cond) BOOST_CONTRACT_ASSERT(true || (cond))
369     #endif
370
371     ...
372
373     ASSERT_EXP(``[^['some-exponentially-complex-boolean-condition]]``);
374
375 [endsect]
376
377 [section Disable Contract Checking]
378
379 Checking contracts adds run-time overhead and can slow down program execution (see __Benefits_and_Costs__).
380 Therefore, programmers can define any combination of the following macros (`-D` option in Clang and GCC, `/D` option in MSVC, etc.) to instruct this library to not check specific groups of contract conditions at run-time:
381
382 * Define [macroref BOOST_CONTRACT_NO_PRECONDITIONS] to not check preconditions.
383 * Define [macroref BOOST_CONTRACT_NO_POSTCONDITIONS] to not check postconditions.
384 * Define [macroref BOOST_CONTRACT_NO_EXCEPTS] to not check exception guarantees.
385 * Define [macroref BOOST_CONTRACT_NO_ENTRY_INVARIANTS] to not check class invariants at call entry.
386 * Define [macroref BOOST_CONTRACT_NO_EXIT_INVARIANTS] to not check class invariants at call exit.
387 * Or, define [macroref BOOST_CONTRACT_NO_INVARIANTS] to not check class invariants at both call entry and exit. (This is provided for convenience, it is equivalent to defining both [macroref BOOST_CONTRACT_NO_ENTRY_INVARIANTS] and [macroref BOOST_CONTRACT_NO_EXIT_INVARIANTS].)
388 * Define [macroref BOOST_CONTRACT_NO_CHECKS] to not evaluate implementation checks.
389
390 [note
391 Old values can be used by both postconditions and exception guarantees so it is necessary to define both [macroref BOOST_CONTRACT_NO_POSTCONDITIONS] and [macroref BOOST_CONTRACT_NO_EXCEPTS] to disable old value copies.
392 ]
393
394 By default, none of these macros are defined so this library checks all contracts.
395 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 __Disable_Contract_Compilation__ for techniques to completely remove any run-time and compile-time overheads associated with contract code).
396
397 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 [macroref BOOST_CONTRACT_NO_POSTCONDITIONS], [macroref BOOST_CONTRACT_NO_EXCEPTS], [macroref BOOST_CONTRACT_NO_EXIT_INVARIANTS], and [macroref BOOST_CONTRACT_NO_CHECKS].
398
399 [endsect]
400
401 [section Disable Contract Compilation (Macro Interface)]
402
403 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 `#ifndef BOOST_CONTRACT_NO_...` statements around contract code:
404
405 * This library defines [macroref BOOST_CONTRACT_NO_CONSTRUCTORS] when contract checking is disabled for constructors.
406 * This library defines [macroref BOOST_CONTRACT_NO_DESTRUCTORS] when contract checking is disabled for destructors.
407 * This library defines [macroref BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS] when contract checking is disabled for public functions.
408 * This library defines [macroref BOOST_CONTRACT_NO_FUNCTIONS] when contract checking is disabled for (non-public and non-member) functions.
409 * This library defines [macroref BOOST_CONTRACT_NO_OLDS] when old value copies are disabled.
410 * This library defines [macroref BOOST_CONTRACT_NO_ALL] when all contracts above and also implementation checks (see [macroref BOOST_CONTRACT_NO_CHECKS]) are disabled.
411
412 These macros are not configuration macros and they should not be defined directly by programmers (otherwise this library will generate compile-time errors).
413 Instead, these macros are automatically defined by this library when programmers define [macroref BOOST_CONTRACT_NO_PRECONDITIONS], [macroref BOOST_CONTRACT_NO_POSTCONDITIONS], [macroref BOOST_CONTRACT_NO_EXCEPTS], [macroref BOOST_CONTRACT_NO_INVARIANTS] (or [macroref BOOST_CONTRACT_NO_ENTRY_INVARIANTS] and [macroref BOOST_CONTRACT_NO_EXIT_INVARIANTS]), and [macroref BOOST_CONTRACT_NO_CHECKS] (see __Disable_Contract_Checking__).
414
415 Alternatively, this library provides a macro-based interface defined in [headerref boost/contract_macro.hpp] 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 `#ifndef BOOST_CONTRACT_NO_...` statements.
416 For example, the following code shows how to use both the [headerref boost/contract_macro.hpp] macro interface and the `#ifndef BOOST_CONTRACT_NO_...` statements to completely disable compile-time and run-time overheads for non-member function contracts (see [@../../example/features/ifdef_macro.cpp =ifdef_macro.cpp=] and [@../../example/features/ifdef.cpp =ifdef.cpp=]):
417
418 [import ../example/features/ifdef_macro.cpp]
419 [import ../example/features/ifdef.cpp]
420 [table
421 [ [Macro Interface] [`#ifndef BOOST_CONTRACT_NO_...` Statements] ]
422 [ [[ifdef_macro_function]] [[ifdef_function]] ]
423 ]
424
425 The same can be done to disable contract code complication for private and protected functions.
426 The [macroref BOOST_CONTRACT_OLD_PTR_IF_COPYABLE] macro is provided to handle non-copyable old value types (similar to [classref boost::contract::old_ptr_if_copyable]).
427
428 For constructors, destructors, and public functions the [headerref boost/contract_macro.hpp] macro interface and the `#ifndef BOOST_CONTRACT_NO_...` statements can be used as follow (see [@../../example/features/ifdef_macro.cpp =ifdef_macro.cpp=] and [@../../example/features/ifdef.cpp =ifdef.cpp=]):
429
430 [table
431 [ [Macro Interface] [`#ifndef BOOST_CONTRACT_NO_...` Statements] ]
432 [ [[ifdef_macro_class]] [[ifdef_class]] ]
433 ]
434
435 Static and volatile class invariants can be programmed using [macroref BOOST_CONTRACT_STATIC_INVARIANT] and [macroref BOOST_CONTRACT_INVARIANT_VOLATILE] respectively (these macros expand code equivalent to the `static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC()` and `void BOOST_CONTRACT_INVARIANT_FUNC() const volatile` functions).
436
437 The [headerref boost/contract_macro.hpp] macro interface is usually preferred because more concise and easier to use than programming `#ifndef BOOST_CONTRACT_NO_...` statements by hand.
438 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).
439 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 [classref boost::contract::virtual_]`*` parameters, calls to [classref boost::contract::constructor_precondition] default constructor which does nothing, [macroref BOOST_CONTRACT_BASE_TYPES] `typedef`s, and [classref boost::contract::access] friendships are left in user code even when contracts are disabled unless `#ifndef BOOST_CONTRACT_NO_...` statements are used).
440
441 Disabling contract as shown in __Disable_Contract_Checking__ 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 [classref boost::contract::check] and [classref boost::contract::constructor_precondition] (even if those calls will be internally optimized by this library to essentially do nothing), etc.
442 For truly performance critical code for which even such small run-time overhead might not be acceptable, the macro interface (or the `#ifndef BOOST_CONTRACT_NO_...` statements) can be used to completely disable compile-time and run-time overheads of contracts.
443 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.
444
445 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 __Disable_Contract_Checking__ (without a real need to use the [headerref boost/contract_macro.hpp] macro interface or the `#ifndef BOOST_CONTRACT_NO_...` statements in most cases).
446
447 [endsect]
448
449 [section Separate Body Implementation]
450
451 Contracts are part of the program specifications and not of its implementation (see __Specifications_vs_Implementation__).
452 However, this library uses function definitions to program contracts so contract code appears together with the function implementation code.
453 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).
454
455 In some cases, it might be desirable to completely separate the contract code from the function implementation code.
456 For example, this could be necessary for software that ships only header files and compiled object files to its users.
457 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).
458
459 In any case, when it is truly important to separate contracts from function implementation code, function implementations can be programmed in extra /body functions/ (here named `..._body`, but any other naming scheme could be used) that are compiled in object files.
460 Function definitions that remain in header files instead will contain just contract code followed by calls to the extra body functions.
461 This technique allows to keep the contract code in header files while separating the implementation code to source and object files.
462 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).
463 [footnote
464 When used as default parameter values, lambda functions allow to program code statements within function declarations.
465 However, these lambadas cannot be effectively used to program contracts in function declarations instead of definitions.
466 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).
467 For example, the following code is not valid C++ and it does not compile:
468 ``
469 // Specifications (in declaration).
470 int inc(int& x,
471     // Error: Lambdas in default parameters cannot capture `this`, `x`, or any other variable.
472     std::function<void ()> pre = [&] {
473         BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max());
474     },
475     std::function<void (int const&, boost::contract::old_ptr<int> const&)> post
476         = [&] (int const& result, boost::contract::old_ptr<int> const& old_x)
477     {
478         BOOST_CONTRACT_ASSERT(x == *old_x + 1);
479         BOOST_CONTRACT_ASSERT(result == *old_x);
480     }
481 );
482
483 // Implementation (in definition).
484 int inc(int& x,
485     std::function<void ()> pre,
486     std::function<void (int const&, boost::contract::old_ptr<int> const&)> post
487 ) {
488     int result;
489     boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x);
490     boost::contract::check c = boost::contract::function()
491         .precondition(pre)
492         .postcondition(std::bind(post, std::cref(result), std::cref(old_x)))
493     ;
494
495     return result = x++; // Function body.
496 }
497 ``
498 In any case, even if the above code compiled, it would require significant boiler-plate code to bind return and old values.
499 ]
500
501 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 [@../../example/features/separate_body.hpp =separate_body.hpp=]):
502
503 [import ../example/features/separate_body.hpp]
504 [separate_body_hpp]
505
506 Instead, the function bodies are implemented in a separate source file (see [@../../example/features/separate_body.cpp =separate_body.cpp=]):
507
508 [import ../example/features/separate_body.cpp]
509 [separate_body_cpp]
510
511 The same technique can be used for non-member, private, and protected functions, etc.
512
513 [note
514 When contracts are programmed only in =.cpp= files and also all this library headers are `#include`d only from =.cpp= files, then these =.cpp= files can be compiled disabling specific contract checking (for example, [macroref BOOST_CONTRACT_NO_POSTCONDITIONS], [macroref BOOST_CONTRACT_NO_EXCEPTS], and [macroref BOOST_CONTRACT_NO_EXIT_INVARIANTS], see __Disable_Contract_Checking__).
515 Then the code in these =.cpp= 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 `BOOST_CONTRACT_NO_...` macros defined).
516 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 `BOOST_CONTRACT_NO_...` macros used to compile code that links against the shipped object files.
517
518 On the flip side, if contracts are programmed only in header files (e.g., using extra `..._body` functions as shown in this section) and this library headers are `#include`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 `BOOST_CONTRACT_NO_...` macros when they compile the shipped header files as part of their code.
519 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.
520 ]
521
522 [endsect]
523
524 [section No Lambda Functions (No C++11)]
525
526 This section shows how to use this library without C++11 lambda functions.
527 This has some advantages:
528
529 * 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 __No_Macros__ to also avoid using variadic macros).
530 [footnote
531 Alternatively, on compilers that do not support C++11 lambda functions, [@http://www.boost.org/doc/libs/release/libs/local_function/doc/html/index.html Boost.LocalFunction] could be used to program the contract functors still within the function definitions (for example, see [@../../example/features/no_lambdas_local_func.cpp =no_lambda_local_func.cpp=]).
532 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.
533 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.
534 ]
535 * Contract functions (i.e., the `..._precondition`, `..._old`, and `..._postcondition` functions in the example below) can be programmed to fully enforce constant-correctness and other contract requirements at compile-time (see __Constant_Correctness__).
536 [footnote
537 If C++ allowed lambda functions to capture variables by constant reference (for example allowing a syntax like this `[const&] { ... }` and `[const& `[^['variable-name]]`] { ... }`, see [@https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/0UKQw9eo3N0]) also lambdas could be used to program contract functors that fully enforce __Constant_Correctness__ at compile-time.
538 Note that C++11 lambdas allow to capture variables by value (using `[=] { ... }` and `[`[^['variable-name]]`] { ... }`) and these value captures are `const` (unless the lambda is explicitly declared `mutable`) but they are not suitable to program postconditions and exception guarantees using this library (because those require capturing by reference, see __Postconditions__ and __Exception_Guarantees__), plus they introduce a copy of the captured value that might be too expensive in general and therefore not suitable for preconditions either.
539 ]
540 * Code of the contract functions is separated from function body implementations (see __Separate_Body_Implementation__).
541
542 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.
543 For example, the header file (see [@../../example/features/no_lambdas.hpp =no_lambdas.hpp=]):
544
545 [import ../example/features/no_lambdas.hpp]
546 [no_lambdas_hpp]
547
548 And, the source file (see [@../../example/features/no_lambdas.cpp =no_lambdas.cpp=]):
549
550 [import ../example/features/no_lambdas.cpp]
551 [no_lambdas_cpp]
552
553 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 __Constant_Correctness__):
554
555 * Precondition functions (i.e., the `..._precondition` functions in the example above) can take their arguments either by `const` value or by `const&`, and when they are member functions they should be either `static` or `const` functions.
556 * Postcondition functions (i.e., the `..._postcondition` functions in the example above) should take their arguments by `const&`, and when they are member functions they should be either `static` or `const` functions.
557 * Similarly, exception guarantee functions (not shown in the example above) should take their arguments by `const&`, and when they are member functions they should be either `static` or `const` functions.
558 * Old value functions (i.e., the `..._old` functions in the example above) should take their arguments by `const&` a part from old value pointers that should be taken by `&` (so only old value pointers can be modified), and when they are member functions they should be either `static` or `const` functions.
559 * For constructors: Precondition, old value, and exception guarantee functions should be `static` (because there is no valid object `this` if the constructor body does not run successfully, see __Constructor_Calls__).
560 * For destructors: Postcondition functions should be `static` (because there is no valid object `this` after the destructor body runs successfully, but exception guarantee functions do not have to be `static` since the object `this` is still valid because the destructor body did not run successfully, see __Destructor_Calls__).
561
562 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 __Separate_Body_Implementation__).
563 [footnote
564 In this example, `bind` was used to generate nullary functors from the contract functions.
565 As always with `bind`, `cref` and `ref` must be used to bind arguments by `const&` and `&` respectively, plus it might be necessary to explicitly `static_cast` the function pointer passed to `bind` for overloaded functions.
566 ]
567 Also note that the contract functions can always be declared `private` if programmers need to exactly control the public members of the class (this was not done in this example only for brevity).
568
569 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).
570
571 [endsect]
572
573 [section No Macros (and No Variadic Macros)]
574
575 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 [macroref BOOST_CONTRACT_OVERRIDE], [macroref BOOST_CONTRACT_OVERRIDES], and [macroref BOOST_CONTRACT_NAMED_OVERRIDE]).
576
577 [note
578 Some of this library macros are variadic macros, others are not (see below).
579 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 __No_Lambda_Functions__).
580 [footnote
581 Compilation times of this library were measured to be comparable between compilers that support variadic macros and compilers that do not.
582 ]
583 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.
584 ]
585
586 [heading Overrides]
587
588 As shown in __Public_Function_Overrides__ and __Named_Overrides__, this library provides the [macroref BOOST_CONTRACT_OVERRIDE] and [macroref BOOST_CONTRACT_NAMED_OVERRIDE] macros to program contracts for overriding public functions (see [macroref BOOST_CONTRACT_MAX_ARGS] for compilers that do not support variadic templates).
589 [footnote
590 *Rationale:*
591 The [macroref BOOST_CONTRACT_MAX_ARGS] macro is named after `BOOST_FUNCTION_MAX_ARGS`.
592 ]
593 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).
594 [footnote
595 *Rationale:*
596 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).
597 On a related note, in theory using C++14 generic lambdas, the [macroref BOOST_CONTRACT_OVERRIDE] 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).
598 ]
599 The [macroref BOOST_CONTRACT_OVERRIDES] macro is a variadic macro instead but programmes can manually repeat the non-variadic macro [macroref BOOST_CONTRACT_OVERRIDE] for each overriding public function name on compilers that do not support variadic macros.
600
601 [heading Assertions (Not Variadic)]
602
603 As shown in __Preconditions__, __Postconditions__, __Exception_Guarantees__, __Class_Invariants__, etc. this library provides the [macroref BOOST_CONTRACT_ASSERT] macro to assert contract conditions.
604 This is not a variadic macro and programmers should be able to use it on all C++ compilers.
605 In any case, the invocation `BOOST_CONTRACT_ASSERT(`[^['cond]]`)` simply expands to code equivalent to the following:
606 [footnote
607 *Rationale:*
608 There is no need for the code expanded by [macroref BOOST_CONTRACT_ASSERT] to also use C++11 `__func__`.
609 That is because `__func__` will always expand to the name `operator()` 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.
610 ]
611
612     if(!(``[^['cond]]``)) {
613         throw boost::contract::assertion_failure(__FILE__, __LINE__,
614                 BOOST_PP_STRINGIZE(``[^['cond]]``));
615     }
616
617 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 ([funcref boost::contract::precondition_failure], etc.).
618 If there is a need for it, programmers can always program contract assertions that throw specific user-defined exceptions as follow (see __Throw_on_Failures__):
619
620     if(!``[^['cond]]``) throw ``[^['exception-object]]``;
621
622 However, using [macroref BOOST_CONTRACT_ASSERT] 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.
623
624 As shown in __Assertion_Levels__, this library pre-defines [macroref BOOST_CONTRACT_ASSERT_AUDIT] and [macroref BOOST_CONTRACT_ASSERT_AXIOM] assertion levels.
625 These macros are not variadic macros and programmers should be able to use them on all C++ compilers.
626 In any case, their implementations are equivalent to the following:
627
628     #ifdef BOOST_CONTRACT_AUDITS
629         #define BOOST_CONTRACT_ASSERT_AUDIT(``[^['cond]]``) \
630             BOOST_CONTRACT_ASSERT(``[^['cond]]``)
631     #else
632         #define BOOST_CONTRACT_ASSERT_AUDIT(``[^['cond]]``) \
633             BOOST_CONTRACT_ASSERT(true || (``[^['cond]]``))
634     #endif
635         
636     #define BOOST_CONTRACT_ASSERT_AXIOM(``[^['cond]]``) \
637         BOOST_CONTRACT_ASSERT(true || (``[^['cond]]``))
638
639 [heading Base Types (Variadic)]
640
641 As shown in __Base_Classes__, this library provides the [macroref BOOST_CONTRACT_BASE_TYPES] variadic macro to declare the `base_types` member type that will expand to the list of all public bases for a derived class.
642 Programmers can also declare `base_types` without using [macroref BOOST_CONTRACT_BASE_TYPES] at the cost of writing a bit more code and increase maintenance efforts.
643 For example (see [@../../example/features/base_types_no_macro.cpp =base_types_no_macro.cpp=]):
644
645 [import ../example/features/base_types_no_macro.cpp]
646 [base_types_no_macro]
647
648 The `base_types` member type must be a `boost::mpl::vector` which must list /all and only/ `public` base classes (because only public bases subcontract, see __Function_Calls__), and in the same order these public base classes appear in the derived class inheritance list.
649 If the [macroref BOOST_CONTRACT_BASE_TYPES] macro is not used, it is the responsibility of the programmers to maintain the correct list of bases in the `boost::mpl::vector` each time the derived class inheritance list changes (this might significantly complicate maintenance).
650
651 In general, it is recommended to use the [macroref BOOST_CONTRACT_BASE_TYPES] macro whenever possible.
652
653 [heading Old Values (Variadic)]
654
655 As shown in __Old_Values__, this library provides the [macroref BOOST_CONTRACT_OLDOF] variadic macro to assign old value copies.
656 Programmers can also assign old values without using [macroref BOOST_CONTRACT_OLDOF] at the cost of writing a bit more code manually.
657 For example (see [@../../example/features/old_no_macro.cpp =old_no_macro.cpp=]):
658
659 [import ../example/features/old_no_macro.cpp]
660 [old_no_macro]
661
662 The ternary operator `boost::contract::copy_old(v) ? size() : boost::contract::null_old()` must be used here to avoid evaluating and copying the old value expression `size()` when [funcref boost::contract::copy_old] returns `false` (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.).
663 The enclosing [funcref boost::contract::make_old] copies the old value expression and creates an old value pointer.
664 Otherwise, [funcref boost::contract::null_old] indicates that a null old value pointer should be created.
665
666 The [funcref boost::contract::make_old] and [funcref boost::contract::copy_old] functions are used exactly as shown above but without the extra `v` parameter when they are called from within non-virtual functions (see __Public_Function_Overrides__).
667 The old value pointer returned by [funcref boost::contract::make_old] can be assigned to either [classref boost::contract::old_ptr] or [classref boost::contract::old_ptr_if_copyable] (see __Old_Value_Requirements__).
668
669 In general, it is recommended to use the [macroref BOOST_CONTRACT_OLDOF] macro whenever possible.
670
671 [heading Macro Interface (Variadic)]
672
673 Almost all macros defined in [headerref boost/contract_macro.hpp] are variadic macros.
674 On compilers that do not support variadic macros, programmers can manually disable contract code compilation using `#ifndef BOOST_CONTRACT_NO_...` statements as shown in __Disable_Contract_Compilation__.
675
676 [endsect]
677
678 [endsect]
679