|
|
|||
Warning, file /include/boost/contract_macro.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 0002 #ifndef BOOST_CONTRACT_MACRO_HPP_ 0003 #define BOOST_CONTRACT_MACRO_HPP_ 0004 0005 // Copyright (C) 2008-2018 Lorenzo Caminiti 0006 // Distributed under the Boost Software License, Version 1.0 (see accompanying 0007 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). 0008 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html 0009 0010 /** @file 0011 Allow to disable contracts to completely remove their compile-time and run-time 0012 overhead. 0013 This header automatically includes all header files <c>boost/contract/\*.hpp</c> 0014 necessary to use its macros. 0015 0016 Almost all the macros defined in this header file are variadic macros. On 0017 compilers that do not support variadic macros, programmers can manually code 0018 <c>\#ifndef BOOST_CONTRACT_NO_...</c> statements instead (see 0019 @RefSect{extras.disable_contract_compilation__macro_interface_, 0020 Disable Contract Compilation}). 0021 */ 0022 0023 // IMPORTANT: Following headers can always be #included (without any #if-guard) 0024 // because they expand to trivial code that does not affect compile-time. These 0025 // headers must always be #included here (without any #if-guard) because they 0026 // define types and macros that are typically left in user code even when 0027 // contracts are disables (these types and macros never affect run-time and 0028 // their definitions are trivial when contracts are disabled so their impact on 0029 // compile-time is negligible). 0030 #include <boost/contract/override.hpp> 0031 #include <boost/contract/base_types.hpp> 0032 #include <boost/contract/core/constructor_precondition.hpp> 0033 #include <boost/contract/core/check_macro.hpp> 0034 #include <boost/contract/core/access.hpp> 0035 #include <boost/contract/core/virtual.hpp> 0036 #include <boost/contract/core/exception.hpp> 0037 #include <boost/contract/core/config.hpp> 0038 0039 #ifndef BOOST_CONTRACT_NO_CONDITIONS 0040 #include <boost/contract/assert.hpp> 0041 #endif 0042 0043 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0044 /** 0045 Program preconditions that can be completely disabled at compile-time. 0046 0047 @c BOOST_CONTRACT_PRECONDITION(f) expands to code equivalent to the 0048 following (note that no code is generated when 0049 @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} is defined): 0050 0051 @code 0052 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 0053 .precondition(f) 0054 #endif 0055 @endcode 0056 0057 Where: 0058 0059 @arg <c><b>f</b></c> is the nullay functor called by this library to 0060 check preconditions @c f(). 0061 Assertions within this functor are usually programmed using 0062 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call 0063 to this functor indicates a contract assertion failure (and will 0064 result in this library calling 0065 @RefFunc{boost::contract::precondition_failure}). 0066 This functor should capture variables by (constant) value, or better 0067 by (constant) reference (to avoid extra copies). 0068 (This is a variadic macro parameter so it can contain commas not 0069 protected by round parenthesis.) 0070 0071 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0072 Disable Contract Compilation}, 0073 @RefSect{tutorial.preconditions, Preconditions} 0074 */ 0075 #define BOOST_CONTRACT_PRECONDITION(...) 0076 #elif !defined(BOOST_CONTRACT_NO_PRECONDITIONS) 0077 #define BOOST_CONTRACT_PRECONDITION(...) .precondition(__VA_ARGS__) 0078 #else 0079 #define BOOST_CONTRACT_PRECONDITION(...) /* nothing */ 0080 #endif 0081 0082 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0083 /** 0084 Program postconditions that can be completely disabled at compile-time. 0085 0086 @c BOOST_CONTRACT_POSTCONDITION(f) expands to code equivalent to the 0087 following (note that no code is generated when 0088 @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS} is defined): 0089 0090 @code 0091 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 0092 .postcondition(f) 0093 #endif 0094 @endcode 0095 0096 Where: 0097 0098 @arg <c><b>f</b></c> is the functor called by this library to check 0099 postconditions @c f() or @c f(result). 0100 Assertions within this functor are usually programmed using 0101 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call 0102 to this functor indicates a contract assertion failure (and will 0103 result in this library calling 0104 @RefFunc{boost::contract::postcondition_failure}). 0105 This functor should capture variables by (constant) references (to 0106 access the values they will have at function exit). 0107 This functor takes the return value (preferably by <c>const&</c>) 0108 @c result as its one single parameter @c f(result) but only for 0109 virtual public functions and public functions overrides, otherwise 0110 it takes no parameter @c f(). 0111 (This is a variadic macro parameter so it can contain commas not 0112 protected by round parenthesis.) 0113 0114 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0115 Disable Contract Compilation}, 0116 @RefSect{tutorial.postconditions, Postconditions} 0117 */ 0118 #define BOOST_CONTRACT_POSTCONDITION(...) 0119 #elif !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) 0120 #define BOOST_CONTRACT_POSTCONDITION(...) .postcondition(__VA_ARGS__) 0121 #else 0122 #define BOOST_CONTRACT_POSTCONDITION(...) /* nothing */ 0123 #endif 0124 0125 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0126 /** 0127 Program exception guarantees that can be completely disabled at 0128 compile-time. 0129 0130 @c BOOST_CONTRACT_EXCEPT(f) expands to code equivalent to the following 0131 (note that no code is generated when @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} 0132 is defined): 0133 0134 @code 0135 #ifndef BOOST_CONTRACT_NO_EXCEPTS 0136 .except(f) 0137 #endif 0138 @endcode 0139 0140 Where: 0141 0142 @arg <c><b>f</b></c> is the nullary functor called by this library to 0143 check exception guarantees @c f(). 0144 Assertions within this functor are usually programmed using 0145 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call 0146 to this functor indicates a contract assertion failure (and will 0147 result in this library calling 0148 @RefFunc{boost::contract::except_failure}). 0149 This functor should capture variables by (constant) references (to 0150 access the values they will have at function exit). 0151 (This is a variadic macro parameter so it can contain commas not 0152 protected by round parenthesis.) 0153 0154 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0155 Disable Contract Compilation}, 0156 @RefSect{tutorial.exception_guarantees, Exception Guarantees} 0157 */ 0158 #define BOOST_CONTRACT_EXCEPT(...) 0159 #elif !defined(BOOST_CONTRACT_NO_EXCEPTS) 0160 #define BOOST_CONTRACT_EXCEPT(...) .except(__VA_ARGS__) 0161 #else 0162 #define BOOST_CONTRACT_EXCEPT(...) /* nothing */ 0163 #endif 0164 0165 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0166 /** 0167 Program old value copies at body that can be completely disabled at 0168 compile-time. 0169 0170 @c BOOST_CONTRACT_OLD(f) expands to code equivalent to the following (note 0171 that no code is generated when @RefMacro{BOOST_CONTRACT_NO_OLDS} is 0172 defined): 0173 0174 @code 0175 #ifndef BOOST_CONTRACT_NO_OLDS 0176 .old(f) 0177 #endif 0178 @endcode 0179 0180 Where: 0181 0182 @arg <c><b>f</b></c> is the nullary functor called by this library 0183 @c f() to assign old value copies just before the body is execute 0184 but after entry invariants (when they apply) and preconditions are 0185 checked. 0186 Old value pointers within this functor call are usually assigned 0187 using @RefMacro{BOOST_CONTRACT_OLDOF}. 0188 Any exception thrown by a call to this functor will result in 0189 this library calling @RefFunc{boost::contract::old_failure} (because 0190 old values could not be copied to check postconditions and exception 0191 guarantees). 0192 This functor should capture old value pointers by references so they 0193 can be assigned (all other variables needed to evaluate old value 0194 expressions can be captured by (constant) value, or better by 0195 (constant) reference to avoid extra copies). 0196 (This is a variadic macro parameter so it can contain commas not 0197 protected by round parenthesis.) 0198 0199 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0200 Disable Contract Compilation}, 0201 @RefSect{advanced.old_values_copied_at_body, 0202 Old Values Copied at Body} 0203 */ 0204 #define BOOST_CONTRACT_OLD(...) 0205 0206 /** 0207 Program old values that can be completely disabled at compile-time for old 0208 value types that are required to be copyable. 0209 0210 This is used to program old value copies for copyable types: 0211 0212 @code 0213 class u { 0214 public: 0215 void f(...) { 0216 BOOST_CONTRACT_OLD_PTR(old_type_a)(old_var_a); // Null... 0217 BOOST_CONTRACT_OLD_PTR(old_type_b)(old_var_b, old_expr_b); // Set. 0218 BOOST_CONTRACT_PUBLIC_FUNCTION(this) 0219 ... 0220 BOOST_CONTRACT_OLD([&] { 0221 old_var_a = BOOST_CONTRACT_OLDOF(old_expr_a); // ...set. 0222 ... 0223 }) 0224 ... 0225 ; 0226 0227 ... // Function body. 0228 } 0229 0230 virtual void g(..., boost::contract::virtual_* v = 0) { 0231 BOOST_CONTRACT_OLD_PTR(old_type_a)(old_var_a); // No `v` 0232 BOOST_CONTRACT_OLD_PTR(old_type_b)(v, old_var_b, old_expr_b); // `v` 0233 BOOST_CONTRACT_PUBLIC_FUNCTION(v, this) 0234 ... 0235 BOOST_CONTRACT_OLD([&] { 0236 old_var_a = BOOST_CONTRACT_OLDOF(v, old_expr_a); // `v` 0237 ... 0238 }) 0239 ... 0240 ; 0241 0242 ... // Function body. 0243 } 0244 0245 ... 0246 }; 0247 @endcode 0248 0249 This is an overloaded variadic macro and it can be used in the following 0250 different ways (note that no code is generated when 0251 @RefMacro{BOOST_CONTRACT_NO_OLDS} is defined). 0252 0253 1\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(old_var)</c> expands to code 0254 equivalent to the following (this leaves the old value pointer null): 0255 0256 @code 0257 #ifndef BOOST_CONTRACT_NO_OLDS 0258 // This declaration does not need to use `v`. 0259 boost::contract::old_ptr<old_type> old_var 0260 #endif 0261 @endcode 0262 0263 2\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(old_var, old_expr)</c> expands to 0264 code equivalent to the following (this initializes the pointer to the 0265 old value copy, but not to be used for virtual public functions and 0266 public function overrides): 0267 0268 @code 0269 #ifndef BOOST_CONTRACT_NO_OLDS 0270 boost::contract::old_ptr<old_type> old_var = 0271 BOOST_CONTRACT_OLDOF(old_expr) 0272 #endif 0273 @endcode 0274 0275 3\. <c>BOOST_CONTRACT_OLD_PTR(old_type)(v, old_var, old_expr)</c> expands to 0276 code equivalent to the following (this initializes the pointer to the 0277 old value copy for virtual public functions and public function 0278 overrides): 0279 0280 @code 0281 #ifndef BOOST_CONTRACT_NO_OLDS 0282 boost::contract::old_ptr<old_type> old_var = 0283 BOOST_CONTRACT_OLDOF(v, old_expr) 0284 #endif 0285 @endcode 0286 0287 Where: 0288 0289 @arg <c><b>old_type</b></c> is the type of the pointed old value. 0290 This type must be copyable (i.e., 0291 <c>boost::contract::is_old_value_copyable<old_type>::value</c> is 0292 @c true), otherwise this pointer will always be null and this 0293 library will generate a compile-time error when the pointer is 0294 dereferenced (see @RefMacro{BOOST_CONTRACT_OLD_PTR_IF_COPYABLE}). 0295 (This is a variadic macro parameter so it can contain commas not 0296 protected by round parenthesis.) 0297 (Rationale: Template parameters like this one are specified to 0298 this library macro interface using their own set of parenthesis 0299 <c>SOME_MACRO(template_params)(other_params)</c>.) 0300 @arg <c><b>v</b></c> is the extra training parameter of type 0301 @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 0302 from the enclosing virtual public function or public function 0303 override declaring the contract. 0304 (This is not a variadic macro parameter but it should never contain 0305 commas because it is an identifier.) 0306 @arg <c><b>old_var</b></c> is the name of the old value pointer variable. 0307 (This is not a variadic macro parameter but it should never contain 0308 commas because it is an identifier.) 0309 @arg <c><b>old_expr</b></c> is the expression to be evaluated and copied 0310 in the old value pointer. 0311 (This is not a variadic macro parameter so any comma it might 0312 contain must be protected by round parenthesis and 0313 <c>BOOST_CONTRACT_OLD_PTR(old_type)(v, old_var, (old_expr))</c> 0314 will always work.) 0315 0316 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0317 Disable Contract Compilation}, 0318 @RefSect{tutorial.old_values, Old Values} 0319 */ 0320 #define BOOST_CONTRACT_OLD_PTR(...) 0321 0322 /** 0323 Program old values that can be completely disabled at compile-time for old 0324 value types that are not required to be copyable. 0325 0326 This is used to program old value copies for types that might or might not 0327 be copyable: 0328 0329 @code 0330 template<typename T> // Type `T` might or not be copyable. 0331 class u { 0332 public: 0333 void f(...) { 0334 BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_a)(old_var_a); 0335 BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_b)(old_var_b, 0336 old_expr_b); 0337 BOOST_CONTRACT_PUBLIC_FUNCTION(this) 0338 ... 0339 BOOST_CONTRACT_OLD([&] { 0340 old_var_a = BOOST_CONTRACT_OLDOF(old_expr_a); 0341 ... 0342 }) 0343 ... // In postconditions or exception guarantees: 0344 if(old_var_a) ... // Always null for non-copyable types. 0345 if(old_var_b) ... // Always null for non-copyable types. 0346 ... 0347 ; 0348 0349 ... // Function body. 0350 } 0351 0352 virtual void g(..., boost::contract::virtual_* v = 0) { 0353 BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_a)(old_var_a); 0354 BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_b)(v, old_var_b, 0355 old_expr_b); 0356 BOOST_CONTRACT_PUBLIC_FUNCTION(v, this) 0357 ... 0358 BOOST_CONTRACT_OLD([&] { 0359 old_var_a = BOOST_CONTRACT_OLDOF(v, old_expr_a); 0360 ... 0361 }) 0362 ... // In postconditions or exception guarantees: 0363 if(old_var_a) ... // Always null for non-copyable types. 0364 if(old_var_b) ... // Always null for non-copyable types. 0365 ... 0366 ; 0367 0368 ... // Function body. 0369 } 0370 0371 ... 0372 }; 0373 @endcode 0374 0375 This is an overloaded variadic macro and it can be used in the following 0376 different ways (note that no code is generated when 0377 @RefMacro{BOOST_CONTRACT_NO_OLDS} is defined). 0378 0379 1\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(old_var)</c> expands to 0380 code equivalent to the following (this leaves the old value pointer 0381 null): 0382 0383 @code 0384 #ifndef BOOST_CONTRACT_NO_OLDS 0385 // This declaration does not need to use `v`. 0386 boost::contract::old_ptr_if_copyable<old_type> old_var 0387 #endif 0388 @endcode 0389 0390 2\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(old_var, old_expr)</c> 0391 expands to code equivalent to the following (this initializes the 0392 pointer to the old value copy, but not to be used for virtual public 0393 functions and public function overrides): 0394 0395 @code 0396 #ifndef BOOST_CONTRACT_NO_OLDS 0397 boost::contract::old_ptr_if_copyable<old_type> old_var = 0398 BOOST_CONTRACT_OLDOF(old_expr) 0399 #endif 0400 @endcode 0401 0402 3\. <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(v, old_var, 0403 old_expr)</c> expands to code equivalent to the following (this 0404 initializes the pointer to the old value copy for virtual public 0405 functions and public function overrides): 0406 0407 @code 0408 #ifndef BOOST_CONTRACT_NO_OLDS 0409 boost::contract::old_ptr_if_copyable<old_type> old_var = 0410 BOOST_CONTRACT_OLDOF(v, old_expr) 0411 #endif 0412 @endcode 0413 0414 Where: 0415 0416 @arg <c><b>old_type</b></c> is the type of the pointed old value. 0417 If this type is not copyable (i.e., 0418 <c>boost::contract::is_old_value_copyable<old_type>::value</c> is 0419 @c false), this pointer will always be null, but this library will 0420 not generate a compile-time error when this pointer is dereferenced 0421 (see @RefMacro{BOOST_CONTRACT_OLD_PTR}). 0422 (This is a variadic macro parameter so it can contain commas not 0423 protected by round parenthesis.) 0424 @arg <c><b>v</b></c> is the extra trailing parameter of type 0425 @RefClass{boost::contract::virtual_}<c>*</c> and default value @c 0 0426 from the enclosing virtual public function or public function 0427 override declaring the contract. 0428 (This is not a variadic macro parameter but it should never contain 0429 commas because it is an identifier.) 0430 @arg <c><b>old_var</b></c> is the name of the old value pointer variable. 0431 (This is not a variadic macro parameter but it should never contain 0432 commas because it is an identifier.) 0433 @arg <c><b>old_expr</b></c> is the expression to be evaluated and copied 0434 in the old value pointer. 0435 (This is not a variadic macro parameter so any comma it might 0436 contain must be protected by round parenthesis and 0437 <c>BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(v, old_var, 0438 (old_expr))</c> will always work.) 0439 0440 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0441 Disable Contract Compilation}, 0442 @RefSect{extras.old_value_requirements__templates_, 0443 Old Value Requirements} 0444 */ 0445 #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...) 0446 #elif !defined(BOOST_CONTRACT_NO_OLDS) 0447 #include <boost/contract/old.hpp> 0448 #include <boost/preprocessor/facilities/overload.hpp> 0449 #include <boost/preprocessor/facilities/empty.hpp> 0450 #include <boost/preprocessor/cat.hpp> 0451 0452 /* PRIVATE */ 0453 0454 #define BOOST_CONTRACT_OLD_VAR_1(ptr) \ 0455 ptr 0456 #define BOOST_CONTRACT_OLD_VAR_2(ptr, expr) \ 0457 ptr = BOOST_CONTRACT_OLDOF(expr) 0458 #define BOOST_CONTRACT_OLD_VAR_3(v, ptr, expr) \ 0459 ptr = BOOST_CONTRACT_OLDOF(v, expr) 0460 0461 #define BOOST_CONTRACT_OLD_VAR_(...) \ 0462 BOOST_PP_CAT(BOOST_PP_OVERLOAD(BOOST_CONTRACT_OLD_VAR_, __VA_ARGS__) \ 0463 (__VA_ARGS__), BOOST_PP_EMPTY()) 0464 0465 /* PUBLIC */ 0466 0467 #define BOOST_CONTRACT_OLD(...) .old(__VA_ARGS__) 0468 0469 #define BOOST_CONTRACT_OLD_PTR(...) \ 0470 boost::contract::old_ptr< __VA_ARGS__ > \ 0471 BOOST_CONTRACT_OLD_VAR_ 0472 0473 #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...) \ 0474 boost::contract::old_ptr_if_copyable< __VA_ARGS__ > \ 0475 BOOST_CONTRACT_OLD_VAR_ 0476 #else 0477 #include <boost/preprocessor/tuple/eat.hpp> 0478 0479 #define BOOST_CONTRACT_OLD(...) /* nothing */ 0480 0481 #define BOOST_CONTRACT_OLD_PTR(...) BOOST_PP_TUPLE_EAT(0) 0482 0483 #define BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...) BOOST_PP_TUPLE_EAT(0) 0484 #endif 0485 0486 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0487 /** 0488 Program (constant) class invariants that can be completely disabled at 0489 compile-time. 0490 0491 @c BOOST_CONTRACT_INVARIANT({ ... }) expands to code equivalent to the 0492 following (note that no code is generated when 0493 @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined): 0494 0495 @code 0496 #ifndef BOOST_CONTRACT_NO_INVARIANTS 0497 void BOOST_CONTRACT_INVARIANT_FUNC() const { 0498 ... 0499 } 0500 #endif 0501 @endcode 0502 0503 Where: 0504 0505 @arg <b>{ ... }</b> is the definition of the function that checks class 0506 invariants for public functions that are not static and not volatile 0507 (see @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT} and 0508 @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}). 0509 The curly parenthesis are mandatory (rationale: this is so the 0510 syntax of this macro resembles mote the syntax of the lambda 0511 functions usually used to specify preconditions, etc.). 0512 Assertions within this function are usually programmed using 0513 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call 0514 to this function indicates a contract assertion failure (and will 0515 result in this library calling either 0516 @RefFunc{boost::contract::entry_invariant_failure} or 0517 @RefFunc{boost::contract::exit_invariant_failure}). 0518 (This is a variadic macro parameter so it can contain commas not 0519 protected by round parenthesis.) 0520 0521 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0522 Disable Contract Compilation}, 0523 @RefSect{tutorial.class_invariants, Class Invariants} 0524 */ 0525 #define BOOST_CONTRACT_INVARIANT(...) 0526 0527 /** 0528 Program volatile class invariants that can be completely disabled at 0529 compile-time. 0530 0531 @c BOOST_CONTRACT_INVARIANT_VOLATILE({ ... }) expands to code equivalent to 0532 the following (note that no code is generated when 0533 @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined): 0534 0535 @code 0536 #ifndef BOOST_CONTRACT_NO_INVARIANTS 0537 void BOOST_CONTRACT_INVARIANT_FUNC() const volatile { 0538 ... 0539 } 0540 #endif 0541 @endcode 0542 0543 Where: 0544 0545 @arg <b>{ ... }</b> is the definition of the function that checks class 0546 invariants for volatile public functions 0547 (see @RefMacro{BOOST_CONTRACT_INVARIANT} and 0548 @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT}). 0549 The curly parenthesis are mandatory. 0550 Assertions within this function are usually programmed using 0551 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call 0552 to this function indicates a contract assertion failure (and will 0553 result in this library calling either 0554 @RefFunc{boost::contract::entry_invariant_failure} or 0555 @RefFunc{boost::contract::exit_invariant_failure}). 0556 (This is a variadic macro parameter so it can contain commas not 0557 protected by round parenthesis.) 0558 0559 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0560 Disable Contract Compilation}, 0561 @RefSect{extras.volatile_public_functions, 0562 Volatile Public Functions} 0563 */ 0564 #define BOOST_CONTRACT_INVARIANT_VOLATILE(...) 0565 0566 /** 0567 Program static class invariants that can be completely disabled at 0568 compile-time. 0569 0570 @c BOOST_CONTRACT_STATIC_INVARIANT({ ... }) expands to code equivalent to 0571 the following (note that no code is generated when 0572 @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined): 0573 0574 @code 0575 #ifndef BOOST_CONTRACT_NO_INVARIANTS 0576 static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() { 0577 ... 0578 } 0579 #endif 0580 @endcode 0581 0582 Where: 0583 0584 @arg <b>{ ... }</b> is the definition of the function that checks class 0585 invariants for static public functions 0586 (see @RefMacro{BOOST_CONTRACT_INVARIANT} and 0587 @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}). 0588 The curly parenthesis are mandatory. 0589 Assertions within this function are usually programmed using 0590 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call 0591 to this function indicates a contract assertion failure (and will 0592 result in this library calling either 0593 @RefFunc{boost::contract::entry_invariant_failure} or 0594 @RefFunc{boost::contract::exit_invariant_failure}). 0595 (This is a variadic macro parameter so it can contain commas not 0596 protected by round parenthesis.) 0597 0598 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0599 Disable Contract Compilation}, 0600 @RefSect{tutorial.class_invariants, Class Invariants} 0601 */ 0602 #define BOOST_CONTRACT_STATIC_INVARIANT(...) 0603 #elif !defined(BOOST_CONTRACT_NO_INVARIANTS) 0604 #include <boost/contract/core/config.hpp> 0605 0606 #define BOOST_CONTRACT_INVARIANT(...) \ 0607 void BOOST_CONTRACT_INVARIANT_FUNC() const __VA_ARGS__ 0608 0609 #define BOOST_CONTRACT_INVARIANT_VOLATILE(...) \ 0610 void BOOST_CONTRACT_INVARIANT_FUNC() const volatile __VA_ARGS__ 0611 0612 #define BOOST_CONTRACT_STATIC_INVARIANT(...) \ 0613 static void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() __VA_ARGS__ 0614 #else 0615 #define BOOST_CONTRACT_INVARIANT(...) /* nothing */ 0616 0617 #define BOOST_CONTRACT_INVARIANT_VOLATILE(...) /* nothing */ 0618 0619 #define BOOST_CONTRACT_STATIC_INVARIANT(...) /* nothing */ 0620 #endif 0621 0622 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0623 /** 0624 Program contracts that can be completely disabled at compile-time for 0625 constructors. 0626 0627 This is used together with @RefMacro{BOOST_CONTRACT_POSTCONDITION}, 0628 @RefMacro{BOOST_CONTRACT_EXCEPT}, and @RefMacro{BOOST_CONTRACT_OLD} to 0629 specify postconditions, exception guarantees, and old value copies at body 0630 that can be completely disabled at compile-time for constructors (see 0631 @RefMacro{BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION} to specify preconditions 0632 for constructors): 0633 0634 @code 0635 class u { 0636 friend class boost::contract::access; 0637 0638 BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile). 0639 BOOST_CONTRACT_ASSERT(...); 0640 ... 0641 }) 0642 0643 public: 0644 u(...) { 0645 BOOST_CONTRACT_OLD_PTR(old_type)(old_var); 0646 BOOST_CONTRACT_CONSTRUCTOR(this) 0647 // No `PRECONDITION` (use `CONSTRUCTOR_PRECONDITION` if needed). 0648 BOOST_CONTRACT_OLD([&] { // Optional. 0649 old_var = BOOST_CONTRACT_OLDOF(old_epxr); 0650 ... 0651 }) 0652 BOOST_CONTRACT_POSTCONDITION([&] { // Optional. 0653 BOOST_CONTRACT_ASSERT(...); 0654 ... 0655 }) 0656 BOOST_CONTRACT_EXCEPT([&] { // Optional. 0657 BOOST_CONTRACT_ASSERT(...); 0658 ... 0659 }) 0660 ; // Trailing `;` is required. 0661 0662 ... // Constructor body. 0663 } 0664 0665 ... 0666 }; 0667 @endcode 0668 0669 For optimization, this can be omitted for constructors that do not have 0670 postconditions and exception guarantees, within classes that have no 0671 invariants. 0672 0673 @c BOOST_CONTRACT_CONSTRUCTOR(obj) expands to code equivalent to the 0674 following (note that no code is generated when 0675 @RefMacro{BOOST_CONTRACT_NO_CONSTRUCTORS} is defined): 0676 0677 @code 0678 #ifndef BOOST_CONTRACT_NO_CONSTRUCTORS 0679 boost::contract::check internal_var = 0680 boost::contract::constructor(obj) 0681 #endif 0682 @endcode 0683 0684 Where: 0685 0686 @arg <c><b>obj</b></c> is the object @c this from the scope of the 0687 enclosing constructor declaring the contract. 0688 Constructors check all class invariants, including static and 0689 volatile invariants (see @RefMacro{BOOST_CONTRACT_INVARIANT}, 0690 @RefMacro{BOOST_CONTRACT_STATIC_INVARIANT}, and 0691 @RefMacro{BOOST_CONTRACT_INVARIANT_VOLATILE}). 0692 (This is a variadic macro parameter so it can contain commas not 0693 protected by round parenthesis.) 0694 @arg <c><b>internal_var</b></c> is a variable name internally generated 0695 by this library (this name is unique but only on different line 0696 numbers so this macro cannot be expanded multiple times on the same 0697 line). 0698 0699 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0700 Disable Contract Compilation}, 0701 @RefSect{tutorial.constructors, Constructors} 0702 */ 0703 #define BOOST_CONTRACT_CONSTRUCTOR(...) 0704 #elif !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) 0705 #include <boost/contract/constructor.hpp> 0706 #include <boost/contract/check.hpp> 0707 #include <boost/contract/detail/name.hpp> 0708 0709 #define BOOST_CONTRACT_CONSTRUCTOR(...) \ 0710 boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ 0711 boost::contract::constructor(__VA_ARGS__) 0712 #else 0713 #define BOOST_CONTRACT_CONSTRUCTOR(...) /* nothing */ 0714 #endif 0715 0716 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0717 /** 0718 Program preconditions that can be disabled at compile-time for constructors. 0719 0720 This is used together with @RefMacro{BOOST_CONTRACT_CONSTRUCTOR} to specify 0721 contracts for constructors. 0722 Constructors that do not have preconditions do not use this macro. 0723 When at least one of the class constructors uses this macro, 0724 @RefClass{boost::contract::constructor_precondition} must be the first and 0725 private base of the class declaring the constructor for which preconditions 0726 are programmed: 0727 0728 @code 0729 class u 0730 #define BASES private boost::contract::constructor_precondition<u>, \ 0731 public b 0732 : BASES 0733 { 0734 friend class boost::contract::access; 0735 0736 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; 0737 #undef BASES 0738 0739 ... 0740 0741 public: 0742 explicit u(unsigned x) : 0743 BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(u)([&] { 0744 BOOST_CONTRACT_ASSERT(x != 0); 0745 }), 0746 b(1 / x) 0747 { 0748 ... 0749 } 0750 0751 ... 0752 }; 0753 @endcode 0754 0755 <c>BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(class_type)(f)</c> expands 0756 to code equivalent to the following (note that when 0757 @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} is defined, this macro trivially 0758 expands to a default constructor call that is internally implemented to do 0759 nothing so this should have minimal to no overhead): 0760 0761 @code 0762 // Guarded only by NO_PRECONDITIONS (and not also by NO_CONSTRUCTORS) 0763 // because for constructor's preconditions (not for postconditions, etc.). 0764 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 0765 boost::contract::constructor_precondition<class_type>(f) 0766 #else // No-op call (likely optimized away, minimal to no overhead). 0767 boost::contract::constructor_precondition<class_type>() 0768 #endif 0769 0770 @endcode 0771 0772 Where: 0773 0774 @arg <c><b>class_type</b></c> is the type of the class containing the 0775 constructor for which preconditions are being programmed. 0776 (This is a variadic macro parameter so it can contain commas not 0777 protected by round parenthesis.) 0778 @arg <c><b>f</b></c> is the nullary functor called by this library to 0779 check constructor preconditions @c f(). 0780 Assertions within this functor call are usually programmed using 0781 @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call 0782 to this functor indicates a contract failure (and will result in 0783 this library calling 0784 @RefFunc{boost::contract::precondition_failure}). 0785 This functor should capture variables by (constant) value, or better 0786 by (constant) reference to avoid extra copies. 0787 (This is a variadic macro parameter so it can contain commas not 0788 protected by round parenthesis.) 0789 0790 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0791 Disable Contract Compilation}, 0792 @RefSect{tutorial.constructors, Constructors} 0793 */ 0794 #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...) 0795 #elif !defined(BOOST_CONTRACT_NO_PRECONDITIONS) // Not NO_CONSTRUCTORS here. 0796 // constructor_precondition.hpp already #included at top. 0797 0798 #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...) \ 0799 boost::contract::constructor_precondition< __VA_ARGS__ > 0800 #else 0801 #include <boost/preprocessor/tuple/eat.hpp> 0802 // constructor_precondition.hpp always #included at top of this file. 0803 0804 #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(...) \ 0805 /* always use default ctor (i.e., do nothing) */ \ 0806 boost::contract::constructor_precondition< __VA_ARGS__ >() \ 0807 BOOST_PP_TUPLE_EAT(0) 0808 #endif 0809 0810 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0811 /** 0812 Program contracts that can be completely disabled at compile-time for 0813 destructors. 0814 0815 This is used together with @RefMacro{BOOST_CONTRACT_POSTCONDITION}, 0816 @RefMacro{BOOST_CONTRACT_EXCEPT}, and @RefMacro{BOOST_CONTRACT_OLD} to 0817 specify postconditions, exception guarantees, and old value copies at body 0818 that can be completely disabled at compile-time for destructors (destructors 0819 cannot have preconditions, see 0820 @RefSect{contract_programming_overview.destructor_calls, Destructor Calls}): 0821 0822 @code 0823 class u { 0824 friend class boost::contract::access; 0825 0826 BOOST_CONTRACT_INVARIANT({ // Optional (as for static and volatile). 0827 BOOST_CONTRACT_ASSERT(...); 0828 ... 0829 }) 0830 0831 public: 0832 ~u() { 0833 BOOST_CONTRACT_OLD_PTR(old_type)(old_var); 0834 BOOST_CONTRACT_DESTRUCTOR(this) 0835 // No `PRECONDITION` (destructors have no preconditions). 0836 BOOST_CONTRACT_OLD([&] { // Optional. 0837 old_var = BOOST_CONTRACT_OLDOF(old_expr); 0838 ... 0839 }) 0840 BOOST_CONTRACT_POSTCONDITION([&] { // Optional. 0841 BOOST_CONTRACT_ASSERT(...); 0842 ... 0843 }) 0844 BOOST_CONTRACT_EXCEPT([&] { // Optional. 0845 BOOST_CONTRACT_ASSERT(...); 0846 ... 0847 }) 0848 ; // Trailing `;` is required. 0849 0850 ... // Destructor body. 0851 } 0852 0853 ... 0854 }; 0855 @endcode 0856 0857 For optimization, this can be omitted for destructors that do not have 0858 postconditions and exception guarantees, within classes that have no 0859 invariants. 0860 0861 @c BOOST_CONTRACT_DESTRUCTOR(obj) expands to code equivalent to the 0862 following (note that no code is generated when 0863 @RefMacro{BOOST_CONTRACT_NO_DESTRUCTORS} is defined): 0864 0865 @code 0866 #ifndef BOOST_CONTRACT_NO_DESTRUCTORS 0867 boost::contract::check internal_var = 0868 boost::contract::destructor(obj) 0869 #endif 0870 @endcode 0871 0872 Where: 0873 0874 @arg <c><b>obj</b></c> is the object @c this from the scope of the 0875 enclosing destructor declaring the contract. 0876 Destructors check all class invariants, including static and 0877 volatile invariants (see @RefSect{tutorial.class_invariants, 0878 Class Invariants} and 0879 @RefSect{extras.volatile_public_functions, 0880 Volatile Public Functions}). 0881 (This is a variadic macro parameter so it can contain commas not 0882 protected by round parenthesis.) 0883 @arg <c><b>internal_var</b></c> is a variable name internally generated 0884 by this library (this name is unique but only on different line 0885 numbers so this macro cannot be expanded multiple times on the same 0886 line). 0887 0888 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0889 Disable Contract Compilation}, 0890 @RefSect{tutorial.destructors, Destructors} 0891 */ 0892 #define BOOST_CONTRACT_DESTRUCTOR(...) 0893 #elif !defined(BOOST_CONTRACT_NO_DESTRUCTORS) 0894 #include <boost/contract/destructor.hpp> 0895 #include <boost/contract/check.hpp> 0896 #include <boost/contract/detail/name.hpp> 0897 0898 #define BOOST_CONTRACT_DESTRUCTOR(...) \ 0899 boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ 0900 boost::contract::destructor(__VA_ARGS__) 0901 #else 0902 #define BOOST_CONTRACT_DESTRUCTOR(...) /* nothing */ 0903 #endif 0904 0905 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0906 /** 0907 Program contracts that can be completely disabled at compile-time for 0908 (non-public) functions. 0909 0910 This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION}, 0911 @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT}, 0912 and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions, 0913 exception guarantees, and old value copies at body that can be completely 0914 disabled at compile-time for (non-public) functions: 0915 0916 @code 0917 void f(...) { 0918 BOOST_CONTRACT_OLD_PTR(old_type)(old_var); 0919 BOOST_CONTRACT_FUNCTION() 0920 BOOST_CONTRACT_PRECONDITION([&] { // Optional. 0921 BOOST_CONTRACT_ASSERT(...); 0922 ... 0923 }) 0924 BOOST_CONTRACT_OLD([&] { // Optional. 0925 old_var = BOOST_CONTRACT_OLDOF(old_expr); 0926 ... 0927 }) 0928 BOOST_CONTRACT_POSTCONDITION([&] { // Optional. 0929 BOOST_CONTRACT_ASSERT(...); 0930 ... 0931 }) 0932 BOOST_CONTRACT_EXCEPT([&] { // Optional. 0933 BOOST_CONTRACT_ASSERT(...); 0934 ... 0935 }) 0936 ; // Trailing `;` is required. 0937 0938 ... // Function body. 0939 } 0940 @endcode 0941 0942 This can be used to program contracts for non-member functions but also for 0943 private and protected functions, lambda functions, loops, arbitrary blocks 0944 of code, etc. 0945 For optimization, this can be omitted for code that does not have 0946 preconditions, postconditions, and exception guarantees. 0947 0948 @c BOOST_CONTRACT_FUNCTION() expands to code equivalent to the following 0949 (note that no code is generated when @RefMacro{BOOST_CONTRACT_NO_FUNCTIONS} 0950 is defined): 0951 0952 @code 0953 #ifndef BOOST_CONTRACT_NO_FUNCTIONS 0954 boost::contract::check internal_var = 0955 boost::contract::function() 0956 #endif 0957 @endcode 0958 0959 Where: 0960 0961 @arg <c><b>internal_var</b></c> is a variable name internally generated 0962 by this library (this name is unique but only on different line 0963 numbers so this macro cannot be expanded multiple times on the same 0964 line). 0965 0966 @see @RefSect{extras.disable_contract_compilation__macro_interface_, 0967 Disable Contract Compilation}, 0968 @RefSect{tutorial.non_member_functions, Non-Member Functions}, 0969 @RefSect{advanced.private_and_protected_functions, 0970 Private and Protected Functions}, 0971 @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__, 0972 Lambdas\, Loops\, Code Blocks} 0973 */ 0974 #define BOOST_CONTRACT_FUNCTION() 0975 #elif !defined(BOOST_CONTRACT_NO_FUNCTIONS) 0976 #include <boost/contract/function.hpp> 0977 #include <boost/contract/check.hpp> 0978 #include <boost/contract/detail/name.hpp> 0979 0980 #define BOOST_CONTRACT_FUNCTION() \ 0981 boost::contract::check BOOST_CONTRACT_DETAIL_NAME2(c, __LINE__) = \ 0982 boost::contract::function() 0983 #else 0984 #include <boost/preprocessor/facilities/empty.hpp> 0985 0986 #define BOOST_CONTRACT_FUNCTION() /* nothing */ 0987 #endif 0988 0989 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 0990 /** 0991 Program contracts that can be completely disabled at compile-time for static 0992 public functions. 0993 0994 This is used together with @RefMacro{BOOST_CONTRACT_PRECONDITION}, 0995 @RefMacro{BOOST_CONTRACT_POSTCONDITION}, @RefMacro{BOOST_CONTRACT_EXCEPT}, 0996 and @RefMacro{BOOST_CONTRACT_OLD} to specify preconditions, postconditions, 0997 exception guarantees, and old value copies at body that can be completely 0998 disabled at compile-time for static public functions: 0999 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
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|