]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/contract_macro.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / contract_macro.hpp
CommitLineData
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
11Allow to disable contracts to completely remove their compile-time and run-time
12overhead.
92f5a8d4 13This header automatically includes all header files <c>boost/contract/\*.hpp</c>
11fdf7f2
TL
14necessary to use its macros.
15
16Almost all the macros defined in this header file are variadic macros. On
17compilers 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_,
20Disable 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