1 2 #ifndef BOOST_CONTRACT_ASSERT_HPP_ 3 #define BOOST_CONTRACT_ASSERT_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 Assert contract conditions. 12 */ 13 14 #include <boost/contract/core/config.hpp> 15 #include <boost/contract/detail/noop.hpp> 16 17 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 18 /** 19 Preferred way to assert contract conditions. 20 21 Any exception thrown from within a contract (preconditions, postconditions, 22 exception guarantees, old value copies at body, class invariants, etc.) is 23 interpreted by this library as a contract failure. 24 Therefore, users can program contract assertions manually throwing an 25 exception when an asserted condition is checked to be @c false (this 26 library will then call the appropriate contract failure handler 27 @RefFunc{boost::contract::precondition_failure}, etc.). 28 However, it is preferred to use this macro because it expands to 29 code that throws @RefClass{boost::contract::assertion_failure} with the 30 correct assertion file name (using <c>__FILE__</c>), line number (using 31 <c>__LINE__</c>), and asserted condition code so to produce informative 32 error messages (C++11 <c>__func__</c> is not used here because in most cases 33 it will simply expand to the internal compiler name of the lambda function 34 used to program the contract conditions adding no specificity to the error 35 message). 36 37 @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, 38 and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels 39 predefined by this library. 40 41 @see @RefSect{tutorial.preconditions, Preconditions}, 42 @RefSect{tutorial.postconditions, Postconditions}, 43 @RefSect{tutorial.exception_guarantees, Exceptions Guarantees}, 44 @RefSect{tutorial.class_invariants, Class Invariants}, 45 @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} 46 47 @param cond Boolean contract condition to check. 48 (This is not a variadic macro parameter so any comma it might 49 contain must be protected by round parenthesis and 50 @c BOOST_CONTRACT_ASSERT((cond)) will always work.) 51 */ 52 // This must be an expression (a trivial one so the compiler can optimize it 53 // away). It cannot an empty code block `{}`, etc. otherwise code like 54 // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL. 55 #define BOOST_CONTRACT_ASSERT(cond) 56 #elif !defined(BOOST_CONTRACT_NO_ALL) 57 #include <boost/contract/detail/assert.hpp> 58 #define BOOST_CONTRACT_ASSERT(cond) \ 59 BOOST_CONTRACT_DETAIL_ASSERT(cond) /* no `;` here */ 60 #else 61 // This must be an expression (a trivial one so the compiler can optimize it 62 // away). It cannot an empty code block `{}`, etc. otherwise code like 63 // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL. 64 #define BOOST_CONTRACT_ASSERT(cond) \ 65 BOOST_CONTRACT_DETAIL_NOOP 66 #endif 67 68 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN 69 /** 70 Preferred way to assert contract conditions that are computationally 71 expensive, at least compared to the computational cost of executing the 72 function body. 73 74 The asserted condition will always be compiled and validated syntactically, 75 but it will not be checked at run-time unless 76 @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default). 77 This macro is defined by code equivalent to: 78 79 @code 80 #ifdef BOOST_CONTRACT_AUDITS 81 #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ 82 BOOST_CONTRACT_ASSERT(cond) 83 #else 84 #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ 85 BOOST_CONTRACT_ASSERT(true || cond) 86 #endif 87 @endcode 88 89 @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, 90 and @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels 91 predefined by this library. 92 If there is a need, programmers are free to implement their own assertion 93 levels defining macros similar to the one above. 94 95 @see @RefSect{extras.assertion_levels, Assertion Levels}, 96 @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} 97 98 @param cond Boolean contract condition to check. 99 (This is not a variadic macro parameter so any comma it might 100 contain must be protected by round parenthesis and 101 @c BOOST_CONTRACT_ASSERT_AUDIT((cond)) will always work.) 102 */ 103 #define BOOST_CONTRACT_ASSERT_AUDIT(cond) 104 #elif defined(BOOST_CONTRACT_AUDITS) 105 #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ 106 BOOST_CONTRACT_ASSERT(cond) 107 #else 108 #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ 109 BOOST_CONTRACT_DETAIL_NOEVAL(cond) 110 #endif 111 112 /** 113 Preferred way to document in the code contract conditions that are 114 computationally prohibitive, at least compared to the computational cost of 115 executing the function body. 116 117 The asserted condition will always be compiled and validated syntactically, but 118 it will never be checked at run-time. 119 This macro is defined by code equivalent to: 120 121 @code 122 #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \ 123 BOOST_CONTRACT_ASSERT(true || cond) 124 @endcode 125 126 @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT}, and 127 @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels predefined 128 by this library. 129 If there is a need, programmers are free to implement their own assertion levels 130 defining macros similar to the one above. 131 132 @see @RefSect{extras.assertion_levels, Assertion Levels}, 133 @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} 134 135 @param cond Boolean contract condition to check. 136 (This is not a variadic macro parameter so any comma it might 137 contain must be protected by round parenthesis and 138 @c BOOST_CONTRACT_ASSERT_AXIOM((cond)) will always work.) 139 */ 140 #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \ 141 BOOST_CONTRACT_DETAIL_NOEVAL(cond) 142 143 #endif // #include guard 144 145