]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | |
2 | #ifndef BOOST_CONTRACT_MACRO_HPP_ | |
3 | #define BOOST_CONTRACT_MACRO_HPP_ | |
4 | ||
5 | // Copyright (C) 2008-2018 Lorenzo Caminiti | |
6 | // Distributed under the Boost Software License, Version 1.0 (see accompanying | |
7 | // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). | |
8 | // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html | |
9 | ||
10 | /** @file | |
11 | Allow to disable contracts to completely remove their compile-time and run-time | |
12 | overhead. | |
92f5a8d4 | 13 | This header automatically includes all header files <c>boost/contract/\*.hpp</c> |
11fdf7f2 TL |
14 | necessary to use its macros. |
15 | ||
16 | Almost all the macros defined in this header file are variadic macros. On | |
17 | compilers that do not support variadic macros, programmers can manually code | |
18 | <c>\#ifndef BOOST_CONTRACT_NO_...</c> statements instead (see | |
19 | @RefSect{extras.disable_contract_compilation__macro_interface_, | |
20 | Disable Contract Compilation}). | |
21 | */ | |
22 | ||
23 | // IMPORTANT: Following headers can always be #included (without any #if-guard) | |
24 | // because they expand to trivial code that does not affect compile-time. These | |
25 | // headers must always be #included here (without any #if-guard) because they | |
26 | // define types and macros that are typically left in user code even when | |
27 | // contracts are disables (these types and macros never affect run-time and | |
28 | // their definitions are trivial when contracts are disabled so their impact on | |
29 | // compile-time is negligible). | |
30 | #include <boost/contract/override.hpp> | |
31 | #include <boost/contract/base_types.hpp> | |
32 | #include <boost/contract/core/constructor_precondition.hpp> | |
33 | #include <boost/contract/core/check_macro.hpp> | |
34 | #include <boost/contract/core/access.hpp> | |
35 | #include <boost/contract/core/virtual.hpp> | |
36 | #include <boost/contract/core/exception.hpp> | |
37 | #include <boost/contract/core/config.hpp> | |
38 | ||
39 | #ifndef BOOST_CONTRACT_NO_CONDITIONS | |
40 | #include <boost/contract/assert.hpp> | |
41 | #endif | |
42 | ||
43 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
44 | /** | |
45 | Program preconditions that can be completely disabled at compile-time. | |
46 | ||
47 | @c BOOST_CONTRACT_PRECONDITION(f) expands to code equivalent to the | |
48 | following (note that no code is generated when | |
49 | @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} is defined): | |
50 | ||
51 | @code | |
52 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
53 | .precondition(f) | |
54 | #endif | |
55 | @endcode | |
56 | ||
57 | Where: | |
58 | ||
59 | @arg <c><b>f</b></c> is the nullay functor called by this library to | |
60 | check preconditions @c f(). | |
61 | Assertions within this functor are usually programmed using | |
62 | @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call | |
63 | to this functor indicates a contract assertion failure (and will | |
64 | result in this library calling | |
65 | @RefFunc{boost::contract::precondition_failure}). | |
66 | This functor should capture variables by (constant) value, or better | |
67 | by (constant) reference (to avoid extra copies). | |
68 | (This is a variadic macro parameter so it can contain commas not | |
69 | protected by round parenthesis.) | |
70 | ||
71 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
72 | Disable Contract Compilation}, | |
73 | @RefSect{tutorial.preconditions, Preconditions} | |
74 | */ | |
75 | #define BOOST_CONTRACT_PRECONDITION(...) | |
76 | #elif !defined(BOOST_CONTRACT_NO_PRECONDITIONS) | |
77 | #define BOOST_CONTRACT_PRECONDITION(...) .precondition(__VA_ARGS__) | |
78 | #else | |
79 | #define BOOST_CONTRACT_PRECONDITION(...) /* nothing */ | |
80 | #endif | |
81 | ||
82 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
83 | /** | |
84 | Program postconditions that can be completely disabled at compile-time. | |
85 | ||
86 | @c BOOST_CONTRACT_POSTCONDITION(f) expands to code equivalent to the | |
87 | following (note that no code is generated when | |
88 | @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} is defined): | |
89 | ||
90 | @code | |
91 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
92 | .postcondition(f) | |
93 | #endif | |
94 | @endcode | |
95 | ||
96 | Where: | |
97 | ||
98 | @arg <c><b>f</b></c> is the functor called by this library to check | |
92f5a8d4 | 99 | postconditions @c f() or @c f(result). |
11fdf7f2 TL |
100 | Assertions within this functor are usually programmed using |
101 | @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call | |
102 | to this functor indicates a contract assertion failure (and will | |
103 | result in this library calling | |
104 | @RefFunc{boost::contract::postcondition_failure}). | |
105 | This functor should capture variables by (constant) references (to | |
106 | access the values they will have at function exit). | |
92f5a8d4 TL |
107 | This functor takes the return value (preferably by <c>const&</c>) |
108 | @c result as its one single parameter @c f(result) but only for | |
109 | virtual public functions and public functions overrides, otherwise | |
110 | it takes no parameter @c f(). | |
11fdf7f2 TL |
111 | (This is a variadic macro parameter so it can contain commas not |
112 | protected by round parenthesis.) | |
113 | ||
114 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
115 | Disable Contract Compilation}, | |
116 | @RefSect{tutorial.postconditions, Postconditions} | |
117 | */ | |
118 | #define BOOST_CONTRACT_POSTCONDITION(...) | |
119 | #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) | |
120 | #define BOOST_CONTRACT_POSTCONDITION(...) .postcondition(__VA_ARGS__) | |
121 | #else | |
122 | #define BOOST_CONTRACT_POSTCONDITION(...) /* nothing */ | |
123 | #endif | |
124 | ||
125 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
126 | /** | |
127 | Program exception guarantees that can be completely disabled at | |
128 | compile-time. | |
129 | ||
130 | @c BOOST_CONTRACT_EXCEPT(f) expands to code equivalent to the following | |
131 | (note that no code is generated when @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} | |
132 | is defined): | |
133 | ||
134 | @code | |
135 | #ifndef BOOST_CONTRACT_NO_EXCEPTS | |
136 | .except(f) | |
137 | #endif | |
138 | @endcode | |
139 | ||
140 | Where: | |
141 | ||
142 | @arg <c><b>f</b></c> is the nullary functor called by this library to | |
143 | check exception guarantees @c f(). | |
144 | Assertions within this functor are usually programmed using | |
145 | @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call | |
146 | to this functor indicates a contract assertion failure (and will | |
147 | result in this library calling | |
148 | @RefFunc{boost::contract::except_failure}). | |
149 | This functor should capture variables by (constant) references (to | |
150 | access the values they will have at function exit). | |
151 | (This is a variadic macro parameter so it can contain commas not | |
152 | protected by round parenthesis.) | |
153 | ||
154 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
155 | Disable Contract Compilation}, | |
156 | @RefSect{tutorial.exception_guarantees, Exception Guarantees} | |
157 | */ | |
158 | #define BOOST_CONTRACT_EXCEPT(...) | |
159 | #elif !defined(BOOST_CONTRACT_NO_EXCEPTS) | |
160 | #define BOOST_CONTRACT_EXCEPT(...) .except(__VA_ARGS__) | |
161 | #else | |
162 | #define BOOST_CONTRACT_EXCEPT(...) /* nothing */ | |
163 | #endif | |
164 | ||
165 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
166 | /** | |
167 | Program old value copies at body that can be completely disabled at | |
168 | compile-time. | |
169 | ||
170 | @c BOOST_CONTRACT_OLD(f) expands to code equivalent to the following (note | |
171 | that no code is generated when @RefMacro{BOOST_CONTRACT_NO_OLDS} is | |
172 | defined): | |
173 | ||
174 | @code | |
175 | #ifndef BOOST_CONTRACT_NO_OLDS | |
176 | .old(f) | |
177 | #endif | |
178 | @endcode | |
179 | ||
180 | Where: | |
181 | ||
182 | @arg <c><b>f</b></c> is the nullary functor called by this library | |
183 | @c f() to assign old value copies just before the body is execute | |
184 | but after entry invariants (when they apply) and preconditions are | |
185 | checked. | |
186 | Old value pointers within this functor call are usually assigned | |
187 | using @RefMacro{BOOST_CONTRACT_OLDOF}. | |
188 | Any exception thrown by a call to this functor will result in | |
189 | this library calling @RefFunc{boost::contract::old_failure} (because | |
190 | old values could not be copied to check postconditions and exception | |
191 | guarantees). | |
192 | This functor should capture old value pointers by references so they | |
193 | can be assigned (all other variables needed to evaluate old value | |
194 | expressions can be captured by (constant) value, or better by | |
195 | (constant) reference to avoid extra copies). | |
196 | (This is a variadic macro parameter so it can contain commas not | |
197 | protected by round parenthesis.) | |
198 | ||
199 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
200 | Disable Contract Compilation}, | |
92f5a8d4 TL |
201 | @RefSect{advanced.old_values_copied_at_body, |
202 | Old Values Copied at Body} | |
11fdf7f2 TL |
203 | */ |
204 | #define BOOST_CONTRACT_OLD(...) | |
205 | ||
206 | /** | |
92f5a8d4 TL |
207 | Program old values that can be completely disabled at compile-time for old |
208 | value types that are required to be copyable. | |
11fdf7f2 TL |
209 | |
210 | This is used to program old value copies for copyable types: | |
211 | ||
212 | @code | |
213 | class u { | |
214 | public: | |
215 | void f(...) { | |
92f5a8d4 TL |
216 | BOOST_CONTRACT_OLD_PTR(old_type_a)(old_var_a); // Null... |
217 | BOOST_CONTRACT_OLD_PTR(old_type_b)(old_var_b, old_expr_b); // Set. | |
11fdf7f2 TL |
218 | BOOST_CONTRACT_PUBLIC_FUNCTION(this) |
219 | ... | |
220 | BOOST_CONTRACT_OLD([&] { | |
92f5a8d4 | 221 | old_var_a = BOOST_CONTRACT_OLDOF(old_expr_a); // ...set. |
11fdf7f2 TL |
222 | ... |
223 | }) | |
224 | ... | |
225 | ; | |
226 | ||
227 | ... // Function body. | |
228 | } | |
229 | ||
230 | virtual void g(..., boost::contract::virtual_* v = 0) { | |
92f5a8d4 TL |
231 | BOOST_CONTRACT_OLD_PTR(old_type_a)(old_var_a); // No `v` |
232 | BOOST_CONTRACT_OLD_PTR(old_type_b)(v, old_var_b, old_expr_b); // `v` | |
11fdf7f2 TL |
233 | BOOST_CONTRACT_PUBLIC_FUNCTION(v, this) |
234 | ... | |
235 | BOOST_CONTRACT_OLD([&] { | |
92f5a8d4 | 236 | old_var_a = BOOST_CONTRACT_OLDOF(v, old_expr_a); // `v` |
11fdf7f2 TL |
237 | ... |
238 | }) | |
239 | ... | |
240 | ; | |
241 | ||
242 | ... // Function body. | |
243 | } | |
244 | ||
245 | ... | |
246 | }; | |
247 | @endcode | |
248 | ||
249 | This is an overloaded variadic macro and it can be used in the following | |
250 | different ways (note that no code is generated when | |
251 | @RefMacro{BOOST_CONTRACT_NO_OLDS} is defined). | |
252 | ||
253 | 1\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(old_var)</c> expands to code | |
254 | equivalent to the following (this leaves the old value pointer null): | |
255 | ||
256 | @code | |
257 | #ifndef BOOST_CONTRACT_NO_OLDS | |
258 | // This declaration does not need to use `v`. | |
259 | boost::contract::old_ptr<old_type> old_var | |
260 | #endif | |
261 | @endcode | |
262 | ||
263 | 2\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(old_var, old_expr)</c> expands to | |
264 | code equivalent to the following (this initializes the pointer to the | |
265 | old value copy, but not to be used for virtual public functions and | |
266 | public function overrides): | |
267 | ||
268 | @code | |
269 | #ifndef BOOST_CONTRACT_NO_OLDS | |
270 | boost::contract::old_ptr<old_type> old_var = | |
271 | BOOST_CONTRACT_OLDOF(old_expr) | |
272 | #endif | |
273 | @endcode | |
274 | ||
275 | 3\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(v, old_var, old_expr)</c> expands to | |
276 | code equivalent to the following (this initializes the pointer to the | |
277 | old value copy for virtual public functions and public function | |
278 | overrides): | |
279 | ||
280 | @code | |
281 | #ifndef BOOST_CONTRACT_NO_OLDS | |
282 | boost::contract::old_ptr<old_type> old_var = | |
283 | BOOST_CONTRACT_OLDOF(v, old_expr) | |
284 | #endif | |
285 | @endcode | |
286 | ||
287 | Where: | |
288 | ||
289 | @arg <c><b>old_type</b></c> is the type of the pointed old value. | |
290 | This type must be copyable (i.e., | |
291 | <c>boost::contract::is_old_value_copyable<old_type>::value</c> is | |
292 | @c true), otherwise this pointer will always be null and this | |
293 | library will generate a compile-time error when the pointer is | |
294 | dereferenced (see @RefMacro{BOOST_CONTRACT_OLD_PTR_IF_COPYABLE}). | |
295 | (This is a variadic macro parameter so it can contain commas not | |
296 | protected by round parenthesis.) | |
92f5a8d4 TL |
297 | (Rationale: Template parameters like this one are specified to |
298 | this library macro interface using their own set of parenthesis | |
299 | <c>SOME_MACRO(template_params)(other_params)</c>.) | |
300 | @arg <c><b>v</b></c> is the extra training parameter of type | |
11fdf7f2 TL |
301 | @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 |
302 | from the enclosing virtual public function or public function | |
303 | override declaring the contract. | |
92f5a8d4 TL |
304 | (This is not a variadic macro parameter but it should never contain |
305 | commas because it is an identifier.) | |
11fdf7f2 TL |
306 | @arg <c><b>old_var</b></c> is the name of the old value pointer variable. |
307 | (This is not a variadic macro parameter but it should never contain | |
308 | commas because it is an identifier.) | |
309 | @arg <c><b>old_expr</b></c> is the expression to be evaluated and copied | |
310 | in the old value pointer. | |
311 | (This is not a variadic macro parameter so any comma it might | |
92f5a8d4 | 312 | contain must be protected by round parenthesis and |
11fdf7f2 TL |
313 | <c>BOOST_CONTRACT_OLD_PTR(old_type)(v, old_var, (old_expr))</c> |
314 | will always work.) | |
315 | ||
316 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
317 | Disable Contract Compilation}, | |
318 | @RefSect{tutorial.old_values, Old Values} | |
319 | */ | |
320 | #define BOOST_CONTRACT_OLD_PTR(...) | |
321 | ||
322 | /** | |
92f5a8d4 TL |
323 | Program old values that can be completely disabled at compile-time for old |
324 | value types that are not required to be copyable. | |
11fdf7f2 TL |
325 | |
326 | This is used to program old value copies for types that might or might not | |
327 | be copyable: | |
328 | ||
329 | @code | |
330 | template<typename T> // Type `T` might or not be copyable. | |
331 | class u { | |
332 | public: | |
333 | void f(...) { | |
334 | BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_a)(old_var_a); | |
335 | BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_b)(old_var_b, | |
336 | old_expr_b); | |
337 | BOOST_CONTRACT_PUBLIC_FUNCTION(this) | |
338 | ... | |
339 | BOOST_CONTRACT_OLD([&] { | |
340 | old_var_a = BOOST_CONTRACT_OLDOF(old_expr_a); | |
341 | ... | |
342 | }) | |
343 | ... // In postconditions or exception guarantees: | |
344 | if(old_var_a) ... // Always null for non-copyable types. | |
345 | if(old_var_b) ... // Always null for non-copyable types. | |
346 | ... | |
347 | ; | |
348 | ||
349 | ... // Function body. | |
350 | } | |
351 | ||
352 | virtual void g(..., boost::contract::virtual_* v = 0) { | |
353 | BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_a)(old_var_a); | |
354 | BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_b)(v, old_var_b, | |
355 | old_expr_b); | |
356 | BOOST_CONTRACT_PUBLIC_FUNCTION(v, this) | |
357 | ... | |
358 | BOOST_CONTRACT_OLD([&] { | |
359 | old_var_a = BOOST_CONTRACT_OLDOF(v, old_expr_a); | |
360 | ... | |
361 | }) | |
362 | ... // In postconditions or exception guarantees: | |
363 | if(old_var_a) ... // Always null for non-copyable types. | |
364 | if(old_var_b) ... // Always null for non-copyable types. | |
365 | ... | |
366 | ; | |
367 | ||
368 | ... // Function body. | |
369 | } | |
370 | ||
371 | ... | |
372 | }; | |
373 | @endcode | |
374 | ||
375 | This is an overloaded variadic macro and it can be used in the following | |
376 | different ways (note that no code is generated when | |
377 | @RefMacro{BOOST_CONTRACT_NO_OLDS} is defined). | |
378 | ||
379 | 1\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(old_var)</c> expands to | |
380 | code equivalent to the following (this leaves the old value pointer | |
381 | null): | |
382 | ||
383 | @code | |
384 | #ifndef BOOST_CONTRACT_NO_OLDS | |
385 | // This declaration does not need to use `v`. | |
386 | boost::contract::old_ptr_if_copyable<old_type> old_var | |
387 | #endif | |
388 | @endcode | |
389 | ||
390 | 2\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(old_var, old_expr)</c> | |
391 | expands to code equivalent to the following (this initializes the | |
392 | pointer to the old value copy, but not to be used for virtual public | |
393 | functions and public function overrides): | |
394 | ||
395 | @code | |
396 | #ifndef BOOST_CONTRACT_NO_OLDS | |
397 | boost::contract::old_ptr_if_copyable<old_type> old_var = | |
398 | BOOST_CONTRACT_OLDOF(old_expr) | |
399 | #endif | |
400 | @endcode | |
401 | ||
402 | 3\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(v, old_var, | |
403 | old_expr)</c> expands to code equivalent to the following (this | |
404 | initializes the pointer to the old value copy for virtual public | |
405 | functions and public function overrides): | |
406 | ||
407 | @code | |
408 | #ifndef BOOST_CONTRACT_NO_OLDS | |
409 | boost::contract::old_ptr_if_copyable<old_type> old_var = | |
410 | BOOST_CONTRACT_OLDOF(v, old_expr) | |
411 | #endif | |
412 | @endcode | |
413 | ||
414 | Where: | |
415 | ||
416 | @arg <c><b>old_type</b></c> is the type of the pointed old value. | |
417 | If this type is not copyable (i.e., | |
418 | <c>boost::contract::is_old_value_copyable<old_type>::value</c> is | |
419 | @c false), this pointer will always be null, but this library will | |
420 | not generate a compile-time error when this pointer is dereferenced | |
421 | (see @RefMacro{BOOST_CONTRACT_OLD_PTR}). | |
422 | (This is a variadic macro parameter so it can contain commas not | |
423 | protected by round parenthesis.) | |
92f5a8d4 | 424 | @arg <c><b>v</b></c> is the extra trailing parameter of type |
11fdf7f2 TL |
425 | @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 |
426 | from the enclosing virtual public function or public function | |
427 | override declaring the contract. | |
92f5a8d4 TL |
428 | (This is not a variadic macro parameter but it should never contain |
429 | commas because it is an identifier.) | |
11fdf7f2 TL |
430 | @arg <c><b>old_var</b></c> is the name of the old value pointer variable. |
431 | (This is not a variadic macro parameter but it should never contain | |
432 | commas because it is an identifier.) | |
433 | @arg <c><b>old_expr</b></c> is the expression to be evaluated and copied | |
434 | in the old value pointer. | |
435 | (This is not a variadic macro parameter so any comma it might | |
92f5a8d4 | 436 | contain must be protected by round parenthesis and |
11fdf7f2 TL |
437 | <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(v, old_var, |
438 | (old_expr))</c> will always work.) | |
439 | ||
440 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
441 | Disable Contract Compilation}, | |
442 | @RefSect{extras.old_value_requirements__templates_, | |
443 | Old Value Requirements} | |
444 | */ | |
445 | #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...) | |
446 | #elif !defined(BOOST_CONTRACT_NO_OLDS) | |
447 | #include <boost/contract/old.hpp> | |
448 | #include <boost/preprocessor/facilities/overload.hpp> | |
449 | #include <boost/preprocessor/facilities/empty.hpp> | |
450 | #include <boost/preprocessor/cat.hpp> | |
451 | ||
452 | /* PRIVATE */ | |
453 | ||
454 | #define BOOST_CONTRACT_OLD_VAR_1(ptr) \ | |
455 | ptr | |
456 | #define BOOST_CONTRACT_OLD_VAR_2(ptr, expr) \ | |
457 | ptr = BOOST_CONTRACT_OLDOF(expr) | |
458 | #define BOOST_CONTRACT_OLD_VAR_3(v, ptr, expr) \ | |
459 | ptr = BOOST_CONTRACT_OLDOF(v, expr) | |
460 | ||
461 | #define BOOST_CONTRACT_OLD_VAR_(...) \ | |
462 | BOOST_PP_CAT(BOOST_PP_OVERLOAD(BOOST_CONTRACT_OLD_VAR_, __VA_ARGS__) \ | |
463 | (__VA_ARGS__), BOOST_PP_EMPTY()) | |
464 | ||
465 | /* PUBLIC */ | |
466 | ||
467 | #define BOOST_CONTRACT_OLD(...) .old(__VA_ARGS__) | |
468 | ||
469 | #define BOOST_CONTRACT_OLD_PTR(...) \ | |
470 | boost::contract::old_ptr< __VA_ARGS__ > \ | |
471 | BOOST_CONTRACT_OLD_VAR_ | |
472 | ||
473 | #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...) \ | |
474 | boost::contract::old_ptr_if_copyable< __VA_ARGS__ > \ | |
475 | BOOST_CONTRACT_OLD_VAR_ | |
476 | #else | |
477 | #include <boost/preprocessor/tuple/eat.hpp> | |
478 | ||
479 | #define BOOST_CONTRACT_OLD(...) /* nothing */ | |
480 | ||
481 | #define BOOST_CONTRACT_OLD_PTR(...) BOOST_PP_TUPLE_EAT(0) | |
482 | ||
483 | #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...) BOOST_PP_TUPLE_EAT(0) | |
484 | #endif | |
485 | ||
486 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
487 | /** | |
488 | Program (constant) class invariants that can be completely disabled at | |
489 | compile-time. | |
490 | ||
491 | @c BOOST_CONTRACT_INVARIANT({ ... }) expands to code equivalent to the | |
492 | following (note that no code is generated when | |
493 | @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined): | |
494 | ||
495 | @code | |
496 | #ifndef BOOST_CONTRACT_NO_INVARIANTS | |
497 | void BOOST_CONTRACT_INVARIANT_FUNC() const { | |
498 | ... | |
499 | } | |
500 | #endif | |
501 | @endcode | |
502 | ||
503 | Where: | |
504 | ||
505 | @arg <b>{ ... }</b> is the definition of the function that checks class | |
506 | invariants for public functions that are not static and not volatile | |
507 | (see @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT} and | |
508 | @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}). | |
92f5a8d4 TL |
509 | The curly parenthesis are mandatory (rationale: this is so the |
510 | syntax of this macro resembles mote the syntax of the lambda | |
511 | functions usually used to specify preconditions, etc.). | |
11fdf7f2 TL |
512 | Assertions within this function are usually programmed using |
513 | @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call | |
514 | to this function indicates a contract assertion failure (and will | |
515 | result in this library calling either | |
516 | @RefFunc{boost::contract::entry_invariant_failure} or | |
517 | @RefFunc{boost::contract::exit_invariant_failure}). | |
518 | (This is a variadic macro parameter so it can contain commas not | |
519 | protected by round parenthesis.) | |
520 | ||
521 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
522 | Disable Contract Compilation}, | |
523 | @RefSect{tutorial.class_invariants, Class Invariants} | |
524 | */ | |
525 | #define BOOST_CONTRACT_INVARIANT(...) | |
526 | ||
527 | /** | |
528 | Program volatile class invariants that can be completely disabled at | |
529 | compile-time. | |
530 | ||
531 | @c BOOST_CONTRACT_INVARIANT_VOLATILE({ ... }) expands to code equivalent to | |
532 | the following (note that no code is generated when | |
533 | @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined): | |
534 | ||
535 | @code | |
536 | #ifndef BOOST_CONTRACT_NO_INVARIANTS | |
537 | void BOOST_CONTRACT_INVARIANT_FUNC() const volatile { | |
538 | ... | |
539 | } | |
540 | #endif | |
541 | @endcode | |
542 | ||
543 | Where: | |
544 | ||
545 | @arg <b>{ ... }</b> is the definition of the function that checks class | |
546 | invariants for volatile public functions | |
547 | (see @RefMacro{BOOST_CONTRACT_INVARIANT} and | |
548 | @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT}). | |
549 | The curly parenthesis are mandatory. | |
550 | Assertions within this function are usually programmed using | |
551 | @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call | |
552 | to this function indicates a contract assertion failure (and will | |
553 | result in this library calling either | |
554 | @RefFunc{boost::contract::entry_invariant_failure} or | |
555 | @RefFunc{boost::contract::exit_invariant_failure}). | |
556 | (This is a variadic macro parameter so it can contain commas not | |
557 | protected by round parenthesis.) | |
558 | ||
559 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
560 | Disable Contract Compilation}, | |
561 | @RefSect{extras.volatile_public_functions, | |
562 | Volatile Public Functions} | |
563 | */ | |
564 | #define BOOST_CONTRACT_INVARIANT_VOLATILE(...) | |
565 | ||
566 | /** | |
567 | Program static class invariants that can be completely disabled at | |
568 | compile-time. | |
569 | ||
570 | @c BOOST_CONTRACT_STATIC_INVARIANT({ ... }) expands to code equivalent to | |
571 | the following (note that no code is generated when | |
572 | @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined): | |
573 | ||
574 | @code | |
575 | #ifndef BOOST_CONTRACT_NO_INVARIANTS | |
576 | static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() { | |
577 | ... | |
578 | } | |
579 | #endif | |
580 | @endcode | |
581 | ||
582 | Where: | |
583 | ||
584 | @arg <b>{ ... }</b> is the definition of the function that checks class | |
585 | invariants for static public functions | |
586 | (see @RefMacro{BOOST_CONTRACT_INVARIANT} and | |
587 | @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}). | |
588 | The curly parenthesis are mandatory. | |
589 | Assertions within this function are usually programmed using | |
590 | @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call | |
591 | to this function indicates a contract assertion failure (and will | |
592 | result in this library calling either | |
593 | @RefFunc{boost::contract::entry_invariant_failure} or | |
594 | @RefFunc{boost::contract::exit_invariant_failure}). | |
595 | (This is a variadic macro parameter so it can contain commas not | |
596 | protected by round parenthesis.) | |
597 | ||
598 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
599 | Disable Contract Compilation}, | |
600 | @RefSect{tutorial.class_invariants, Class Invariants} | |
601 | */ | |
602 | #define BOOST_CONTRACT_STATIC_INVARIANT(...) | |
603 | #elif !defined(BOOST_CONTRACT_NO_INVARIANTS) | |
604 | #include <boost/contract/core/config.hpp> | |
605 | ||
606 | #define BOOST_CONTRACT_INVARIANT(...) \ | |
607 | void BOOST_CONTRACT_INVARIANT_FUNC() const __VA_ARGS__ | |
608 | ||
609 | #define BOOST_CONTRACT_INVARIANT_VOLATILE(...) \ | |
610 | void BOOST_CONTRACT_INVARIANT_FUNC() const volatile __VA_ARGS__ | |
611 | ||
612 | #define BOOST_CONTRACT_STATIC_INVARIANT(...) \ | |
613 | static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() __VA_ARGS__ | |
614 | #else | |
615 | #define BOOST_CONTRACT_INVARIANT(...) /* nothing */ | |
616 | ||
617 | #define BOOST_CONTRACT_INVARIANT_VOLATILE(...) /* nothing */ | |
618 | ||
619 | #define BOOST_CONTRACT_STATIC_INVARIANT(...) /* nothing */ | |
620 | #endif | |
621 | ||
622 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
623 | /** | |
624 | Program contracts that can be completely disabled at compile-time for | |
625 | constructors. | |
626 | ||
627 | This is used together with @RefMacro{BOOST_CONTRACT_POSTCONDITION}, | |
628 | @RefMacro{BOOST_CONTRACT_EXCEPT}, and @RefMacro{BOOST_CONTRACT_OLD} to | |
629 | specify postconditions, exception guarantees, and old value copies at body | |
630 | that can be completely disabled at compile-time for constructors (see | |
631 | @RefMacro{BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION} to specify preconditions | |
632 | for constructors): | |
633 | ||
634 | @code | |
635 | class u { | |
636 | friend class boost::contract::access; | |
637 | ||
638 | BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile). | |
639 | BOOST_CONTRACT_ASSERT(...); | |
640 | ... | |
641 | }) | |
642 | ||
643 | public: | |
644 | u(...) { | |
645 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
646 | BOOST_CONTRACT_CONSTRUCTOR(this) | |
647 | // No `PRECONDITION` (use `CONSTRUCTOR_PRECONDITION` if needed). | |
648 | BOOST_CONTRACT_OLD([&] { // Optional. | |
649 | old_var = BOOST_CONTRACT_OLDOF(old_epxr); | |
650 | ... | |
651 | }) | |
652 | BOOST_CONTRACT_POSTCONDITION([&] { // Optional. | |
653 | BOOST_CONTRACT_ASSERT(...); | |
654 | ... | |
655 | }) | |
656 | BOOST_CONTRACT_EXCEPT([&] { // Optional. | |
657 | BOOST_CONTRACT_ASSERT(...); | |
658 | ... | |
659 | }) | |
92f5a8d4 | 660 | ; // Trailing `;` is required. |
11fdf7f2 TL |
661 | |
662 | ... // Constructor body. | |
663 | } | |
664 | ||
665 | ... | |
666 | }; | |
667 | @endcode | |
668 | ||
669 | For optimization, this can be omitted for constructors that do not have | |
670 | postconditions and exception guarantees, within classes that have no | |
671 | invariants. | |
672 | ||
673 | @c BOOST_CONTRACT_CONSTRUCTOR(obj) expands to code equivalent to the | |
674 | following (note that no code is generated when | |
675 | @RefMacro{BOOST_CONTRACT_NO_CONSTRUCTORS} is defined): | |
676 | ||
677 | @code | |
678 | #ifndef BOOST_CONTRACT_NO_CONSTRUCTORS | |
679 | boost::contract::check internal_var = | |
680 | boost::contract::constructor(obj) | |
681 | #endif | |
682 | @endcode | |
683 | ||
684 | Where: | |
685 | ||
686 | @arg <c><b>obj</b></c> is the object @c this from the scope of the | |
687 | enclosing constructor declaring the contract. | |
688 | Constructors check all class invariants, including static and | |
689 | volatile invariants (see @RefMacro{BOOST_CONTRACT_INVARIANT}, | |
690 | @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT}, and | |
691 | @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}). | |
692 | (This is a variadic macro parameter so it can contain commas not | |
693 | protected by round parenthesis.) | |
694 | @arg <c><b>internal_var</b></c> is a variable name internally generated | |
695 | by this library (this name is unique but only on different line | |
696 | numbers so this macro cannot be expanded multiple times on the same | |
697 | line). | |
698 | ||
699 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
700 | Disable Contract Compilation}, | |
701 | @RefSect{tutorial.constructors, Constructors} | |
702 | */ | |
703 | #define BOOST_CONTRACT_CONSTRUCTOR(...) | |
704 | #elif !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) | |
705 | #include <boost/contract/constructor.hpp> | |
706 | #include <boost/contract/check.hpp> | |
707 | #include <boost/contract/detail/name.hpp> | |
708 | ||
709 | #define BOOST_CONTRACT_CONSTRUCTOR(...) \ | |
710 | boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ | |
711 | boost::contract::constructor(__VA_ARGS__) | |
712 | #else | |
713 | #define BOOST_CONTRACT_CONSTRUCTOR(...) /* nothing */ | |
714 | #endif | |
715 | ||
716 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
717 | /** | |
718 | Program preconditions that can be disabled at compile-time for constructors. | |
719 | ||
720 | This is used together with @RefMacro{BOOST_CONTRACT_CONSTRUCTOR} to specify | |
721 | contracts for constructors. | |
722 | Constructors that do not have preconditions do not use this macro. | |
723 | When at least one of the class constructors uses this macro, | |
724 | @RefClass{boost::contract::constructor_precondition} must be the first and | |
92f5a8d4 TL |
725 | private base of the class declaring the constructor for which preconditions |
726 | are programmed: | |
11fdf7f2 TL |
727 | |
728 | @code | |
729 | class u | |
730 | #define BASES private boost::contract::constructor_precondition<u>, \ | |
731 | public b | |
732 | : BASES | |
733 | { | |
92f5a8d4 TL |
734 | friend class boost::contract::access; |
735 | ||
736 | typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; | |
11fdf7f2 TL |
737 | #undef BASES |
738 | ||
92f5a8d4 TL |
739 | ... |
740 | ||
11fdf7f2 TL |
741 | public: |
742 | explicit u(unsigned x) : | |
743 | BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(u)([&] { | |
744 | BOOST_CONTRACT_ASSERT(x != 0); | |
745 | }), | |
92f5a8d4 | 746 | b(1 / x) |
11fdf7f2 TL |
747 | { |
748 | ... | |
749 | } | |
750 | ||
751 | ... | |
752 | }; | |
753 | @endcode | |
754 | ||
755 | <c>BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(class_type)(f)</c> expands | |
756 | to code equivalent to the following (note that when | |
757 | @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} is defined, this macro trivially | |
758 | expands to a default constructor call that is internally implemented to do | |
759 | nothing so this should have minimal to no overhead): | |
760 | ||
761 | @code | |
762 | // Guarded only by NO_PRECONDITIONS (and not also by NO_CONSTRUCTORS) | |
763 | // because for constructor's preconditions (not for postconditions, etc.). | |
764 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
765 | boost::contract::constructor_precondition<class_type>(f) | |
92f5a8d4 | 766 | #else // No-op call (likely optimized away, minimal to no overhead). |
11fdf7f2 TL |
767 | boost::contract::constructor_precondition<class_type>() |
768 | #endif | |
769 | ||
770 | @endcode | |
771 | ||
772 | Where: | |
773 | ||
774 | @arg <c><b>class_type</b></c> is the type of the class containing the | |
775 | constructor for which preconditions are being programmed. | |
776 | (This is a variadic macro parameter so it can contain commas not | |
777 | protected by round parenthesis.) | |
778 | @arg <c><b>f</b></c> is the nullary functor called by this library to | |
779 | check constructor preconditions @c f(). | |
780 | Assertions within this functor call are usually programmed using | |
781 | @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call | |
782 | to this functor indicates a contract failure (and will result in | |
783 | this library calling | |
784 | @RefFunc{boost::contract::precondition_failure}). | |
785 | This functor should capture variables by (constant) value, or better | |
786 | by (constant) reference to avoid extra copies. | |
787 | (This is a variadic macro parameter so it can contain commas not | |
788 | protected by round parenthesis.) | |
789 | ||
790 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
791 | Disable Contract Compilation}, | |
792 | @RefSect{tutorial.constructors, Constructors} | |
793 | */ | |
794 | #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...) | |
795 | #elif !defined(BOOST_CONTRACT_NO_PRECONDITIONS) // Not NO_CONSTRUCTORS here. | |
796 | // constructor_precondition.hpp already #included at top. | |
797 | ||
798 | #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...) \ | |
799 | boost::contract::constructor_precondition< __VA_ARGS__ > | |
800 | #else | |
801 | #include <boost/preprocessor/tuple/eat.hpp> | |
802 | // constructor_precondition.hpp always #included at top of this file. | |
803 | ||
804 | #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...) \ | |
805 | /* always use default ctor (i.e., do nothing) */ \ | |
806 | boost::contract::constructor_precondition< __VA_ARGS__ >() \ | |
807 | BOOST_PP_TUPLE_EAT(0) | |
808 | #endif | |
809 | ||
810 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
811 | /** | |
812 | Program contracts that can be completely disabled at compile-time for | |
813 | destructors. | |
814 | ||
815 | This is used together with @RefMacro{BOOST_CONTRACT_POSTCONDITION}, | |
816 | @RefMacro{BOOST_CONTRACT_EXCEPT}, and @RefMacro{BOOST_CONTRACT_OLD} to | |
817 | specify postconditions, exception guarantees, and old value copies at body | |
818 | that can be completely disabled at compile-time for destructors (destructors | |
819 | cannot have preconditions, see | |
820 | @RefSect{contract_programming_overview.destructor_calls, Destructor Calls}): | |
821 | ||
822 | @code | |
823 | class u { | |
824 | friend class boost::contract::access; | |
825 | ||
826 | BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile). | |
827 | BOOST_CONTRACT_ASSERT(...); | |
828 | ... | |
829 | }) | |
830 | ||
831 | public: | |
832 | ~u() { | |
833 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
834 | BOOST_CONTRACT_DESTRUCTOR(this) | |
835 | // No `PRECONDITION` (destructors have no preconditions). | |
836 | BOOST_CONTRACT_OLD([&] { // Optional. | |
837 | old_var = BOOST_CONTRACT_OLDOF(old_expr); | |
838 | ... | |
839 | }) | |
840 | BOOST_CONTRACT_POSTCONDITION([&] { // Optional. | |
841 | BOOST_CONTRACT_ASSERT(...); | |
842 | ... | |
843 | }) | |
844 | BOOST_CONTRACT_EXCEPT([&] { // Optional. | |
845 | BOOST_CONTRACT_ASSERT(...); | |
846 | ... | |
847 | }) | |
92f5a8d4 | 848 | ; // Trailing `;` is required. |
11fdf7f2 TL |
849 | |
850 | ... // Destructor body. | |
851 | } | |
852 | ||
853 | ... | |
854 | }; | |
855 | @endcode | |
856 | ||
857 | For optimization, this can be omitted for destructors that do not have | |
858 | postconditions and exception guarantees, within classes that have no | |
859 | invariants. | |
860 | ||
861 | @c BOOST_CONTRACT_DESTRUCTOR(obj) expands to code equivalent to the | |
862 | following (note that no code is generated when | |
863 | @RefMacro{BOOST_CONTRACT_NO_DESTRUCTORS} is defined): | |
864 | ||
865 | @code | |
866 | #ifndef BOOST_CONTRACT_NO_DESTRUCTORS | |
867 | boost::contract::check internal_var = | |
868 | boost::contract::destructor(obj) | |
869 | #endif | |
870 | @endcode | |
871 | ||
872 | Where: | |
873 | ||
874 | @arg <c><b>obj</b></c> is the object @c this from the scope of the | |
875 | enclosing destructor declaring the contract. | |
876 | Destructors check all class invariants, including static and | |
877 | volatile invariants (see @RefSect{tutorial.class_invariants, | |
878 | Class Invariants} and | |
879 | @RefSect{extras.volatile_public_functions, | |
880 | Volatile Public Functions}). | |
881 | (This is a variadic macro parameter so it can contain commas not | |
882 | protected by round parenthesis.) | |
883 | @arg <c><b>internal_var</b></c> is a variable name internally generated | |
884 | by this library (this name is unique but only on different line | |
885 | numbers so this macro cannot be expanded multiple times on the same | |
886 | line). | |
887 | ||
888 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
889 | Disable Contract Compilation}, | |
890 | @RefSect{tutorial.destructors, Destructors} | |
891 | */ | |
892 | #define BOOST_CONTRACT_DESTRUCTOR(...) | |
893 | #elif !defined(BOOST_CONTRACT_NO_DESTRUCTORS) | |
894 | #include <boost/contract/destructor.hpp> | |
895 | #include <boost/contract/check.hpp> | |
896 | #include <boost/contract/detail/name.hpp> | |
897 | ||
898 | #define BOOST_CONTRACT_DESTRUCTOR(...) \ | |
899 | boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ | |
900 | boost::contract::destructor(__VA_ARGS__) | |
901 | #else | |
902 | #define BOOST_CONTRACT_DESTRUCTOR(...) /* nothing */ | |
903 | #endif | |
904 | ||
905 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
906 | /** | |
907 | Program contracts that can be completely disabled at compile-time for | |
908 | (non-public) functions. | |
909 | ||
910 | This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION}, | |
911 | @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT}, | |
912 | and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions, | |
913 | exception guarantees, and old value copies at body that can be completely | |
914 | disabled at compile-time for (non-public) functions: | |
915 | ||
916 | @code | |
917 | void f(...) { | |
918 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
919 | BOOST_CONTRACT_FUNCTION() | |
920 | BOOST_CONTRACT_PRECONDITION([&] { // Optional. | |
921 | BOOST_CONTRACT_ASSERT(...); | |
922 | ... | |
923 | }) | |
924 | BOOST_CONTRACT_OLD([&] { // Optional. | |
925 | old_var = BOOST_CONTRACT_OLDOF(old_expr); | |
926 | ... | |
927 | }) | |
928 | BOOST_CONTRACT_POSTCONDITION([&] { // Optional. | |
929 | BOOST_CONTRACT_ASSERT(...); | |
930 | ... | |
931 | }) | |
932 | BOOST_CONTRACT_EXCEPT([&] { // Optional. | |
933 | BOOST_CONTRACT_ASSERT(...); | |
934 | ... | |
935 | }) | |
92f5a8d4 | 936 | ; // Trailing `;` is required. |
11fdf7f2 TL |
937 | |
938 | ... // Function body. | |
939 | } | |
940 | @endcode | |
941 | ||
942 | This can be used to program contracts for non-member functions but also for | |
943 | private and protected functions, lambda functions, loops, arbitrary blocks | |
944 | of code, etc. | |
945 | For optimization, this can be omitted for code that does not have | |
946 | preconditions, postconditions, and exception guarantees. | |
947 | ||
948 | @c BOOST_CONTRACT_FUNCTION() expands to code equivalent to the following | |
949 | (note that no code is generated when @RefMacro{BOOST_CONTRACT_NO_FUNCTIONS} | |
950 | is defined): | |
951 | ||
952 | @code | |
953 | #ifndef BOOST_CONTRACT_NO_FUNCTIONS | |
954 | boost::contract::check internal_var = | |
955 | boost::contract::function() | |
956 | #endif | |
957 | @endcode | |
958 | ||
959 | Where: | |
960 | ||
961 | @arg <c><b>internal_var</b></c> is a variable name internally generated | |
962 | by this library (this name is unique but only on different line | |
963 | numbers so this macro cannot be expanded multiple times on the same | |
964 | line). | |
965 | ||
966 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
967 | Disable Contract Compilation}, | |
968 | @RefSect{tutorial.non_member_functions, Non-Member Functions}, | |
969 | @RefSect{advanced.private_and_protected_functions, | |
970 | Private and Protected Functions}, | |
971 | @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__, | |
972 | Lambdas\, Loops\, Code Blocks} | |
973 | */ | |
974 | #define BOOST_CONTRACT_FUNCTION() | |
975 | #elif !defined(BOOST_CONTRACT_NO_FUNCTIONS) | |
976 | #include <boost/contract/function.hpp> | |
977 | #include <boost/contract/check.hpp> | |
978 | #include <boost/contract/detail/name.hpp> | |
979 | ||
980 | #define BOOST_CONTRACT_FUNCTION() \ | |
981 | boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ | |
982 | boost::contract::function() | |
983 | #else | |
984 | #include <boost/preprocessor/facilities/empty.hpp> | |
985 | ||
986 | #define BOOST_CONTRACT_FUNCTION() /* nothing */ | |
987 | #endif | |
988 | ||
989 | #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN | |
990 | /** | |
991 | Program contracts that can be completely disabled at compile-time for static | |
992 | public functions. | |
993 | ||
994 | This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION}, | |
995 | @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT}, | |
996 | and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions, | |
997 | exception guarantees, and old value copies at body that can be completely | |
998 | disabled at compile-time for static public functions: | |
999 | ||
1000 | @code | |
1001 | class u { | |
1002 | friend class boost::contract::access; | |
1003 | ||
1004 | BOOST_CONTRACT_STATIC_INVARIANT({ // Optional (as for non-static). | |
1005 | BOOST_CONTRACT_ASSERT(...); | |
1006 | ... | |
1007 | }) | |
1008 | ||
1009 | public: | |
1010 | static void f(...) { | |
1011 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
1012 | BOOST_CONTRACT_PUBLIC_FUNCTION(u) | |
1013 | BOOST_CONTRACT_PRECONDITION([&] { // Optional. | |
1014 | BOOST_CONTRACT_ASSERT(...); | |
1015 | ... | |
1016 | }) | |
1017 | BOOST_CONTRACT_OLD([&] { // Optional. | |
1018 | old_var = BOOST_CONTRACT_OLDOF(old_expr); | |
1019 | ... | |
1020 | }) | |
1021 | BOOST_CONTRACT_POSTCONDITION([&] { // Optional. | |
1022 | BOOST_CONTRACT_ASSERT(...); | |
1023 | ... | |
1024 | }) | |
1025 | BOOST_CONTRACT_EXCEPT([&] { // Optional. | |
1026 | BOOST_CONTRACT_ASSERT(...); | |
1027 | ... | |
1028 | }) | |
92f5a8d4 | 1029 | ; // Trailing `;` is required. |
11fdf7f2 TL |
1030 | |
1031 | ... // Function body. | |
1032 | } | |
1033 | ||
1034 | ... | |
1035 | }; | |
1036 | @endcode | |
1037 | ||
1038 | For optimization, this can be omitted for static public functions that do | |
1039 | not have preconditions, postconditions and exception guarantees, within | |
1040 | classes that have no static invariants. | |
1041 | ||
1042 | @c BOOST_CONTRACT_STATIC_PUBLIC_FUNCTION(class_type) expands to code | |
1043 | equivalent to the following (note that no code is generated when | |
1044 | @RefMacro{BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS} is defined): | |
1045 | ||
1046 | @code | |
1047 | #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS | |
1048 | boost::contract::check internal_var = | |
1049 | boost::contract::public_function<class_type>() | |
1050 | #endif | |
1051 | @endcode | |
1052 | ||
1053 | Where: | |
1054 | ||
1055 | @arg <c><b>class_type</b></c> is the type of the class containing the | |
1056 | static public function declaring the contract. | |
1057 | (This is a variadic macro parameter so it can contain commas not | |
1058 | protected by round parenthesis.) | |
1059 | @arg <c><b>internal_var</b></c> is a variable name internally generated | |
1060 | by this library (this name is unique but only on different line | |
1061 | numbers so this macro cannot be expanded multiple times on the same | |
1062 | line). | |
1063 | ||
1064 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
1065 | Disable Contract Compilation}, | |
1066 | @RefSect{tutorial.static_public_functions, Static Public Functions} | |
1067 | */ | |
1068 | #define BOOST_CONTRACT_STATIC_PUBLIC_FUNCTION(...) | |
1069 | ||
1070 | /** | |
1071 | Program contracts that can be completely disabled at compile-time for | |
1072 | non-static public functions that do not override. | |
1073 | ||
1074 | This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION}, | |
1075 | @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT}, | |
1076 | and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions, | |
1077 | exception guarantees, and old value copies at body that can be completely | |
1078 | disabled at compile-time for non-static public functions (virtual or not, | |
1079 | void or not) that do not override: | |
1080 | ||
1081 | @code | |
1082 | class u { | |
1083 | friend class boost::contract::access; | |
1084 | ||
1085 | BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile). | |
1086 | BOOST_CONTRACT_ASSERT(...); | |
1087 | ... | |
1088 | }) | |
1089 | ||
1090 | public: | |
1091 | // Non-virtual (same if void). | |
1092 | t f(...) { | |
1093 | t result; | |
1094 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
1095 | BOOST_CONTRACT_PUBLIC_FUNCTION(this) | |
1096 | BOOST_CONTRACT_PRECONDITION([&] { // Optional. | |
1097 | BOOST_CONTRACT_ASSERT(...); | |
1098 | ... | |
1099 | }) | |
1100 | BOOST_CONTRACT_OLD([&] { // Optional. | |
1101 | old_var = BOOST_CONTRACT_OLDOF(old_expr); | |
1102 | ... | |
1103 | }) | |
1104 | BOOST_CONTRACT_POSTCONDITION([&] { // Optional. | |
1105 | BOOST_CONTRACT_ASSERT(...); | |
1106 | ... | |
1107 | }) | |
1108 | BOOST_CONTRACT_EXCEPT([&] { // Optional. | |
1109 | BOOST_CONTRACT_ASSERT(...); | |
1110 | ... | |
1111 | }) | |
92f5a8d4 | 1112 | ; // Trailing `;` is required. |
11fdf7f2 TL |
1113 | |
1114 | ... // Function body (use `return result = return_expr`). | |
1115 | } | |
1116 | ||
1117 | // Virtual and void. | |
1118 | virtual void g(..., boost::contract::virtual_* v = 0) { | |
1119 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
1120 | BOOST_CONTRACT_PUBLIC_FUNCTION(v, this) | |
1121 | ... | |
1122 | BOOST_CONTRACT_OLD([&] { // Optional. | |
1123 | old_var = BOOST_CONTRACT_OLDOF(v, old_expr); | |
1124 | ... | |
1125 | }) | |
1126 | ... | |
92f5a8d4 | 1127 | ; // Trailing `;` is required. |
11fdf7f2 TL |
1128 | |
1129 | ... // Function body. | |
1130 | } | |
1131 | ||
1132 | // Virtual and non-void. | |
1133 | virtual t h(..., boost::contract::virtual_* v = 0) { | |
1134 | t result; | |
1135 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
1136 | BOOST_CONTRACT_PUBLIC_FUNCTION(v, result, this) | |
1137 | ... | |
1138 | BOOST_CONTRACT_OLD([&] { // Optional. | |
1139 | old_var = BOOST_CONTRACT_OLDOF(v, old_expr); | |
1140 | ... | |
1141 | }) | |
1142 | BOOST_CONTRACT_POSTCONDITION([&] (t const& result) { // Optional | |
1143 | BOOST_CONTRACT_ASSERT(...); | |
1144 | ... | |
1145 | }) | |
1146 | ... | |
92f5a8d4 | 1147 | ; // Trailing `;` is required. |
11fdf7f2 TL |
1148 | |
1149 | ... // Function body (use `return result = return_expr`). | |
1150 | } | |
1151 | ||
1152 | ... | |
1153 | }; | |
1154 | @endcode | |
1155 | ||
1156 | For optimization, this can be omitted for non-virtual public functions that | |
1157 | do not have preconditions, postconditions and exception guarantees, within | |
1158 | classes that have no invariants. | |
1159 | Virtual public functions should always use | |
1160 | @RefMacro{BOOST_CONTRACT_PUBLIC_FUNCTION} otherwise this library will not | |
1161 | be able to correctly use them for subcontracting. | |
1162 | ||
1163 | This is an overloaded variadic macro and it can be used in the following | |
1164 | different ways (note that no code is generated when | |
1165 | @RefMacro{BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS} is defined). | |
1166 | ||
1167 | 1\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION(obj)</c> expands to code | |
1168 | equivalent to the following (for non-virtual public functions that are | |
1169 | not static and do not override, returning void or not): | |
1170 | ||
1171 | @code | |
1172 | #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS | |
1173 | boost::contract::check internal_var = | |
1174 | boost::contract::public_function(obj) | |
1175 | #endif | |
1176 | @endcode | |
1177 | ||
1178 | 2\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION(v, obj)</c> expands to code | |
92f5a8d4 TL |
1179 | equivalent to the following (for virtual public functions that do not |
1180 | override, returning void): | |
11fdf7f2 TL |
1181 | |
1182 | @code | |
1183 | #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS | |
1184 | boost::contract::check internal_var = | |
1185 | boost::contract::public_function(v, obj) | |
1186 | #endif | |
1187 | @endcode | |
1188 | ||
1189 | 3\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION(v, r, obj)</c> expands to code | |
92f5a8d4 TL |
1190 | equivalent to the following (for virtual public functions that do not |
1191 | override, not returning void): | |
11fdf7f2 TL |
1192 | |
1193 | @code | |
1194 | #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS | |
1195 | boost::contract::check internal_var = | |
1196 | boost::contract::public_function(v, r, obj) | |
1197 | #endif | |
1198 | @endcode | |
1199 | ||
1200 | Where (these are all variadic macro parameters so they can contain commas | |
1201 | not protected by round parenthesis): | |
1202 | ||
1203 | @arg <c><b>v</b></c> is the extra parameter of type | |
1204 | @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 | |
1205 | from the enclosing virtual public function declaring the contract. | |
1206 | @arg <c><b>r</b></c> is a reference to the return value of the enclosing | |
1207 | virtual public function declaring the contract. | |
1208 | This is usually a local variable declared by the enclosing virtual | |
1209 | public function just before the contract, but programmers must set | |
1210 | it to the actual value being returned by the function at each | |
1211 | @c return statement. | |
1212 | @arg <c><b>obj</b></c> is the object @c this from the scope of the | |
1213 | enclosing public function declaring the contract. | |
1214 | This object might be mutable, @c const, @c volatile, or | |
1215 | <c>const volatile</c> depending on the cv-qualifier of the enclosing | |
1216 | function (volatile public functions will check volatile class | |
1217 | invariants, see @RefSect{extras.volatile_public_functions, | |
1218 | Volatile Public Functions}). | |
1219 | @arg <c><b>internal_var</b></c> is a variable name internally generated | |
1220 | by this library (this name is unique but only on different line | |
1221 | numbers so this macro cannot be expanded multiple times on the same | |
1222 | line). | |
1223 | ||
1224 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
1225 | Disable Contract Compilation}, | |
1226 | @RefSect{tutorial.public_functions, Public Functions}, | |
1227 | @RefSect{tutorial.virtual_public_functions, | |
1228 | Virtual Public Functions} | |
1229 | */ | |
1230 | #define BOOST_CONTRACT_PUBLIC_FUNCTION(...) | |
1231 | ||
1232 | /** | |
1233 | Program contracts that can be completely disabled at compile-time for | |
1234 | public function overrides. | |
1235 | ||
1236 | This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION}, | |
1237 | @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT}, | |
1238 | and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions, | |
1239 | exception guarantees, and old value copies at body that can be completely | |
1240 | disabled at compile-time for public function overrides (virtual or not): | |
1241 | ||
1242 | @code | |
1243 | class u | |
1244 | #define BASES private boost::contract::constructor_precondition<u>, \ | |
1245 | public b, private w | |
1246 | : BASES | |
1247 | { | |
1248 | friend class boost::contract::access; | |
1249 | ||
1250 | typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; | |
1251 | #undef BASES | |
1252 | ||
1253 | BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile). | |
1254 | BOOST_CONTRACT_ASSERT(...); | |
1255 | ... | |
1256 | }) | |
1257 | ||
1258 | BOOST_CONTRACT_OVERRIDES(f, g) | |
1259 | ||
1260 | public: | |
1261 | // Override from `b::f`, and void. | |
1262 | void f(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) { | |
1263 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
1264 | BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_f)( | |
1265 | v, &u::f, this, a_1, ..., a_n) | |
1266 | BOOST_CONTRACT_PRECONDITION([&] { // Optional. | |
1267 | BOOST_CONTRACT_ASSERT(...); | |
1268 | ... | |
1269 | }) | |
1270 | BOOST_CONTRACT_OLD([&] { // Optional. | |
1271 | old_var = BOOST_CONTRACT_OLDOF(v, old_expr); | |
1272 | ... | |
1273 | }) | |
1274 | BOOST_CONTRACT_POSTCONDITION([&] { // Optional. | |
1275 | BOOST_CONTRACT_ASSERT(...); | |
1276 | ... | |
1277 | }) | |
1278 | BOOST_CONTRACT_EXCEPT([&] { // Optional. | |
1279 | BOOST_CONTRACT_ASSERT(...); | |
1280 | ... | |
1281 | }) | |
92f5a8d4 | 1282 | ; // Trailing `;` is required. |
11fdf7f2 TL |
1283 | |
1284 | ... // Function body. | |
1285 | } | |
1286 | ||
1287 | // Override from `b::g`, and void. | |
1288 | t g(t_1 a_1, ..., t_n a_n, boost::contract::virtual_* v = 0) { | |
1289 | t result; | |
1290 | BOOST_CONTRACT_OLD_PTR(old_type)(old_var); | |
1291 | BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_g)( | |
1292 | v, result, &u::g, this, a_1, ..., a_n) | |
1293 | ... | |
1294 | BOOST_CONTRACT_OLD([&] { // Optional. | |
1295 | old_var = BOOST_CONTRACT_OLDOF(v, old_expr); | |
1296 | ... | |
1297 | }) | |
1298 | BOOST_CONTRACT_POSTCONDITION([&] (t const& result) { // Optional | |
1299 | BOOST_CONTRACT_ASSERT(...); | |
1300 | ... | |
1301 | }) | |
1302 | ... | |
92f5a8d4 | 1303 | ; // Trailing `;` is required. |
11fdf7f2 TL |
1304 | |
1305 | ... // Function body (use `return result = return_expr`). | |
1306 | } | |
1307 | ||
1308 | ... | |
1309 | }; | |
1310 | @endcode | |
1311 | ||
1312 | Public function overrides should always use | |
1313 | @RefMacro{BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE} otherwise this library | |
1314 | will not be able to correctly use it for subcontracting. | |
1315 | ||
1316 | This is an overloaded variadic macro and it can be used in the following | |
1317 | different ways (note that no code is generated when | |
1318 | @RefMacro{BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS} is defined). | |
1319 | ||
1320 | 1\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_type)(v, f, obj, | |
1321 | ...)</c> expands to code equivalent to the following (for public | |
1322 | function overrides that return void): | |
1323 | ||
1324 | @code | |
1325 | #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS | |
1326 | boost::contract::check internal_var = boost::contract:: | |
1327 | public_function<override_type>(v, f, obj, ...) | |
1328 | #endif | |
1329 | @endcode | |
1330 | ||
1331 | 2\. <c>BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_type)(v, r, f, obj, | |
1332 | ...)</c> expands to code equivalent to the following (for public | |
1333 | function overrides that do not return void): | |
1334 | ||
1335 | @code | |
1336 | #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS | |
1337 | boost::contract::check internal_var = boost::contract:: | |
1338 | public_function<override_type>(v, r, f, obj, ...) | |
1339 | #endif | |
1340 | @endcode | |
1341 | ||
1342 | Where (these are all variadic macro parameters so they can contain commas | |
1343 | not protected by round parenthesis): | |
1344 | ||
1345 | @arg <c><b>override_type</b></c> is the type | |
1346 | <c>override_<i>function-name</i></c> declared using the | |
1347 | @RefMacro{BOOST_CONTRACT_OVERRIDE} or related macros. | |
1348 | @arg <c><b>v</b></c> is the extra parameter of type | |
1349 | @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 | |
1350 | from the enclosing virtual public function declaring the contract. | |
1351 | @arg <c><b>r</b></c> is a reference to the return value of the enclosing | |
1352 | virtual public function declaring the contract. | |
1353 | This is usually a local variable declared by the enclosing virtual | |
1354 | public function just before the contract, but programmers must set | |
1355 | it to the actual value being returned by the function at each | |
1356 | @c return statement. | |
1357 | @arg <c><b>f</b></c> is a pointer to the enclosing public function | |
1358 | override declaring the contract. | |
1359 | @arg <c><b>obj</b></c> is the object @c this from the scope of the | |
1360 | enclosing public function declaring the contract. | |
1361 | This object might be mutable, @c const, @c volatile, or | |
1362 | <c>const volatile</c> depending on the cv-qualifier of the enclosing | |
1363 | function (volatile public functions will check volatile class | |
1364 | invariants, see @RefSect{extras.volatile_public_functions, | |
1365 | Volatile Public Functions}). | |
1366 | @arg <c><b>...</b></c> is a variadic macro parameter listing all the | |
1367 | arguments passed to the enclosing public function override declaring | |
92f5a8d4 TL |
1368 | the contract (by reference and in the order they appear in the |
1369 | enclosing function declaration), but excluding the trailing | |
1370 | argument @c v. | |
11fdf7f2 TL |
1371 | @arg <c><b>internal_var</b></c> is a variable name internally generated |
1372 | by this library (this name is unique but only on different line | |
1373 | numbers so this macro cannot be expanded multiple times on the same | |
1374 | line). | |
1375 | ||
1376 | @see @RefSect{extras.disable_contract_compilation__macro_interface_, | |
1377 | Disable Contract Compilation}, | |
1378 | @RefSect{tutorial.public_function_overrides__subcontracting_, | |
1379 | Public Function Overrides} | |
1380 | */ | |
1381 | #define BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(...) | |
1382 | #elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS) | |
1383 | #include <boost/contract/public_function.hpp> | |
1384 | #include <boost/contract/check.hpp> | |
1385 | #include <boost/contract/detail/name.hpp> | |
1386 | ||
1387 | #define BOOST_CONTRACT_STATIC_PUBLIC_FUNCTION(...) \ | |
1388 | boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ | |
1389 | boost::contract::public_function< __VA_ARGS__ >() | |
1390 | ||
1391 | #define BOOST_CONTRACT_PUBLIC_FUNCTION(...) \ | |
1392 | boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ | |
1393 | boost::contract::public_function(__VA_ARGS__) | |
1394 | ||
1395 | #define BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(...) \ | |
1396 | boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ | |
1397 | boost::contract::public_function<__VA_ARGS__> | |
1398 | #else | |
1399 | #include <boost/preprocessor/tuple/eat.hpp> | |
1400 | ||
1401 | #define BOOST_CONTRACT_STATIC_PUBLIC_FUNCTION(...) /* nothing */ | |
1402 | ||
1403 | #define BOOST_CONTRACT_PUBLIC_FUNCTION(...) /* nothing */ | |
1404 | ||
1405 | #define BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(...) BOOST_PP_TUPLE_EAT(0) | |
1406 | #endif | |
1407 | ||
1408 | #endif // #include guard | |
1409 |