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. 13 This header automatically includes all header files <c>boost/contract/\*.hpp</c> 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 99 postconditions @c f() or @c f(result). 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). 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(). 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}, 201 @RefSect{advanced.old_values_copied_at_body, 202 Old Values Copied at Body} 203 */ 204 #define BOOST_CONTRACT_OLD(...) 205 206 /** 207 Program old values that can be completely disabled at compile-time for old 208 value types that are required to be copyable. 209 210 This is used to program old value copies for copyable types: 211 212 @code 213 class u { 214 public: 215 void f(...) { 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. 218 BOOST_CONTRACT_PUBLIC_FUNCTION(this) 219 ... 220 BOOST_CONTRACT_OLD([&] { 221 old_var_a = BOOST_CONTRACT_OLDOF(old_expr_a); // ...set. 222 ... 223 }) 224 ... 225 ; 226 227 ... // Function body. 228 } 229 230 virtual void g(..., boost::contract::virtual_* v = 0) { 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` 233 BOOST_CONTRACT_PUBLIC_FUNCTION(v, this) 234 ... 235 BOOST_CONTRACT_OLD([&] { 236 old_var_a = BOOST_CONTRACT_OLDOF(v, old_expr_a); // `v` 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.) 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 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. 304 (This is not a variadic macro parameter but it should never contain 305 commas because it is an identifier.) 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 312 contain must be protected by round parenthesis and 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 /** 323 Program old values that can be completely disabled at compile-time for old 324 value types that are not required to be copyable. 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.) 424 @arg <c><b>v</b></c> is the extra trailing parameter of type 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. 428 (This is not a variadic macro parameter but it should never contain 429 commas because it is an identifier.) 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 436 contain must be protected by round parenthesis and 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}). 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.). 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 }) 660 ; // Trailing `;` is required. 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 725 private base of the class declaring the constructor for which preconditions 726 are programmed: 727 728 @code 729 class u 730 #define BASES private boost::contract::constructor_precondition<u>, \ 731 public b 732 : BASES 733 { 734 friend class boost::contract::access; 735 736 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; 737 #undef BASES 738 739 ... 740 741 public: 742 explicit u(unsigned x) : 743 BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(u)([&] { 744 BOOST_CONTRACT_ASSERT(x != 0); 745 }), 746 b(1 / x) 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) 766 #else // No-op call (likely optimized away, minimal to no overhead). 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 }) 848 ; // Trailing `;` is required. 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 }) 936 ; // Trailing `;` is required. 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 }) 1029 ; // Trailing `;` is required. 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 }) 1112 ; // Trailing `;` is required. 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 ... 1127 ; // Trailing `;` is required. 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 ... 1147 ; // Trailing `;` is required. 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 1179 equivalent to the following (for virtual public functions that do not 1180 override, returning void): 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 1190 equivalent to the following (for virtual public functions that do not 1191 override, not returning void): 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 }) 1282 ; // Trailing `;` is required. 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 ... 1303 ; // Trailing `;` is required. 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 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. 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 1410