|
|
|||
File indexing completed on 2025-12-16 09:45:02
0001 0002 #ifndef BOOST_CONTRACT_CHECK_HPP_ 0003 #define BOOST_CONTRACT_CHECK_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 RAII object that checks contracts. 0012 */ 0013 0014 #include <boost/contract/core/config.hpp> 0015 #include <boost/contract/core/check_macro.hpp> 0016 #include <boost/contract/core/specify.hpp> 0017 #include <boost/contract/core/exception.hpp> // For set_... (if always in code). 0018 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ 0019 defined(BOOST_CONTRACT_STATIC_LINK) 0020 #include <boost/contract/detail/condition/cond_base.hpp> 0021 #include <boost/contract/detail/auto_ptr.hpp> 0022 #include <boost/contract/detail/debug.hpp> 0023 #endif 0024 #include <boost/contract/detail/check.hpp> 0025 #include <boost/config.hpp> 0026 0027 /* PRIVATE */ 0028 0029 /** @cond */ 0030 0031 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ 0032 defined(BOOST_CONTRACT_STATIC_LINK) 0033 #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) \ 0034 : cond_(const_cast<contract_type&>(contract).cond_.release()) \ 0035 { \ 0036 BOOST_CONTRACT_DETAIL_DEBUG(cond_); \ 0037 cond_->initialize(); \ 0038 } 0039 #else 0040 #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) {} 0041 #endif 0042 0043 /** @endcond */ 0044 0045 /* CODE */ 0046 0047 namespace boost { namespace contract { 0048 0049 /** 0050 RAII object that checks the contracts. 0051 0052 In general, when this object is constructed it checks class invariants at entry, 0053 preconditions, and makes old value copies at body. 0054 When it is destructed, it checks class invariants at exist, postconditions, and 0055 exception guarantees. 0056 This object enforces the following (see 0057 @RefSect{contract_programming_overview, Contract Programming Overview}): 0058 0059 @li Postconditions are checked only if the body does not throw an exception. 0060 @li Exceptions guarantees are checked only if the body throws an exception. 0061 @li Constructor entry never checks class invariants. 0062 @li Destructor exit checks class invariants only if the body throws an 0063 exception (even if destructors should usually not be programmed to throw 0064 exceptions in C++ and they are implicitly declared @c noexcept since C++11). 0065 @li Static invariants are always checked at entry and exit (and regardless of 0066 the body throwing exceptions or not). 0067 0068 When used this way, this object is constructed and initialized to the return 0069 value of one of the contract functions @RefFunc{boost::contract::function}, 0070 @RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor}, 0071 or @RefFunc{boost::contract::public_function}. 0072 In addition to that, this object can be constructed from a nullary functor when 0073 it is used to program implementation checks. 0074 0075 @see @RefSect{tutorial, Tutorial}, 0076 @RefSect{advanced.implementation_checks, Implementation Checks} 0077 */ 0078 class check { // Copy ctor only (as move via ptr release). 0079 public: 0080 // NOTE: Unfortunately, Apple compilers define a `check(...)` macro that 0081 // clashes with the name of this class. In the following code, 0082 // BOOST_PREVENT_MACRO_SUBSTITUTION is used to workaround these name 0083 // clashes. In user code, `check c = ...` syntax is typically used also 0084 // avoiding clashes. 0085 0086 /** 0087 Construct this object for implementation checks. 0088 0089 This can be used to program checks within implementation code (body, etc.). 0090 This constructor is not declared @c explicit so initializations can use 0091 assignment syntax @c =. 0092 0093 @b Throws: This can throw in case programmers specify contract failure 0094 handlers that throw exceptions instead of terminating the 0095 program (see 0096 @RefSect{advanced.throw_on_failures__and__noexcept__, 0097 Throw on Failure}). 0098 0099 @param f Nullary functor that asserts implementation checks. @c f() will 0100 be called as soon as this object is constructed at the point it 0101 is declared within the implementation code (see 0102 @RefSect{advanced.implementation_checks, 0103 Implementation Checks}). 0104 */ 0105 template<typename F> // Cannot check `if(f) ...` as f can be a lambda. 0106 // f must be a valid callable object (not null func ptr, empty ftor, etc. 0107 /* implicit */ check 0108 /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( 0109 F const& f) { 0110 BOOST_CONTRACT_DETAIL_CHECK({ f(); }) 0111 } 0112 0113 /** 0114 Construct this object copying it from the specified one. 0115 0116 This object will check the contract, the copied-from object will not (i.e., 0117 contract check ownership is transferred from the copied object to the new 0118 object being created by this constructor). 0119 0120 @param other Copied-from object. 0121 */ 0122 check /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( 0123 check const& other) 0124 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ 0125 defined(BOOST_CONTRACT_STATIC_LINK) 0126 // Copy ctor moves cond_ pointer to dest. 0127 : cond_(const_cast<check&>(other).cond_.release()) 0128 #endif 0129 {} 0130 0131 /** 0132 Construct this object to check the specified contract. 0133 0134 This checks class invariants at entry (if those were specified for the given 0135 contract). 0136 This constructor is not declared @c explicit so initializations can use 0137 assignment syntax @c =. 0138 0139 @b Throws: This can throw in case programmers specify contract failure 0140 handlers that throw exceptions instead of terminating the 0141 program (see 0142 @RefSect{advanced.throw_on_failures__and__noexcept__, 0143 Throw on Failure}). 0144 0145 @param contract Contract to be checked (usually the return value of 0146 @RefFunc{boost::contract::function} or 0147 @RefFunc{boost::contract::public_function}). 0148 0149 @tparam VirtualResult Return type of the enclosing function declaring the 0150 contract if that is either a virtual or an 0151 overriding public function, otherwise this is always 0152 @c void. 0153 (Usually this template parameter is automatically 0154 deduced by C++ and it does not need to be explicitly 0155 specified by programmers.) 0156 */ 0157 template<typename VirtualResult> 0158 /* implicit */ check 0159 /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( 0160 specify_precondition_old_postcondition_except<VirtualResult> const& 0161 contract 0162 ) 0163 #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN 0164 BOOST_CONTRACT_CHECK_CTOR_DEF_( 0165 specify_precondition_old_postcondition_except<VirtualResult>) 0166 #else 0167 ; 0168 #endif 0169 0170 /** 0171 Construct this object to check the specified contract. 0172 0173 This checks class invariants at entry and preconditions (if any of those 0174 were specified for the given contract). 0175 This constructor is not declared @c explicit so initializations can use 0176 assignment syntax @c =. 0177 0178 @b Throws: This can throw in case programmers specify contract failure 0179 handlers that throw exceptions instead of terminating the 0180 program (see 0181 @RefSect{advanced.throw_on_failures__and__noexcept__, 0182 Throw on Failure}). 0183 0184 @param contract Contract to be checked (usually the return value of 0185 @RefFunc{boost::contract::function}, 0186 @RefFunc{boost::contract::constructor}, 0187 @RefFunc{boost::contract::destructor}, or 0188 @RefFunc{boost::contract::public_function}). 0189 0190 @tparam VirtualResult Return type of the enclosing function declaring the 0191 contract if that is either a virtual or an 0192 overriding public function, otherwise this is always 0193 @c void. 0194 (Usually this template parameter is automatically 0195 deduced by C++ and it does not need to be explicitly 0196 specified by programmers.) 0197 */ 0198 template<typename VirtualResult> 0199 /* implicit */ check 0200 /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( 0201 specify_old_postcondition_except<VirtualResult> const& contract) 0202 #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN 0203 BOOST_CONTRACT_CHECK_CTOR_DEF_( 0204 specify_old_postcondition_except<VirtualResult>) 0205 #else 0206 ; 0207 #endif 0208 0209 /** 0210 Construct this object to check the specified contract. 0211 0212 This checks class invariants at entry and preconditions then it makes old 0213 value copies at body (if any of those were specified for the given 0214 contract). 0215 This constructor is not declared @c explicit so initializations can use 0216 assignment syntax @c =. 0217 0218 @b Throws: This can throw in case programmers specify contract failure 0219 handlers that throw exceptions instead of terminating te 0220 program (see 0221 @RefSect{advanced.throw_on_failures__and__noexcept__, 0222 Throw on Failure}). 0223 0224 @param contract Contract to be checked (usually the return value of 0225 @RefFunc{boost::contract::function}, 0226 @RefFunc{boost::contract::constructor}, 0227 @RefFunc{boost::contract::destructor}, or 0228 @RefFunc{boost::contract::public_function}). 0229 0230 @tparam VirtualResult Return type of the enclosing function declaring the 0231 contract if that is either a virtual or an 0232 overriding public function, otherwise this is always 0233 @c void. 0234 (Usually this template parameter is automatically 0235 deduced by C++ and it does not need to be explicitly 0236 specified by programmers.) 0237 */ 0238 template<typename VirtualResult> 0239 /* implicit */ check 0240 /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( 0241 specify_postcondition_except<VirtualResult> const& contract) 0242 #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN 0243 BOOST_CONTRACT_CHECK_CTOR_DEF_( 0244 specify_postcondition_except<VirtualResult>) 0245 #else 0246 ; 0247 #endif 0248 0249 /** 0250 Construct this object to check the specified contract. 0251 0252 This checks class invariants at entry and preconditions then it makes old 0253 value copies at body, plus the destructor of this object will also check 0254 postconditions in this case (if any of those were specified for the given 0255 contract). 0256 This constructor is not declared @c explicit so initializations can use 0257 assignment syntax @c =. 0258 0259 @b Throws: This can throw in case programmers specify contract failure 0260 handlers that throw exceptions instead of terminating the 0261 program (see 0262 @RefSect{advanced.throw_on_failures__and__noexcept__, 0263 Throw on Failure}). 0264 0265 @param contract Contract to be checked (usually the return value of 0266 @RefFunc{boost::contract::function}, 0267 @RefFunc{boost::contract::constructor}, 0268 @RefFunc{boost::contract::destructor}, or 0269 @RefFunc{boost::contract::public_function}). 0270 0271 @tparam VirtualResult Return type of the enclosing function declaring the 0272 contract if that is either a virtual or an 0273 overriding public function, otherwise this is always 0274 @c void. 0275 (Usually this template parameter is automatically 0276 deduced by C++ and it does not need to be explicitly 0277 specified by programmers.) 0278 */ 0279 /* implicit */ check 0280 /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( 0281 specify_except const& contract) 0282 #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN 0283 BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_except) 0284 #else 0285 ; 0286 #endif 0287 0288 /** 0289 Construct this object to check the specified contract. 0290 0291 This checks class invariants at entry and preconditions then it makes old 0292 value copies at body, plus the destructor of this object will also check 0293 postconditions and exception guarantees in this case (if any of those were 0294 specified for the given contract). 0295 This constructor is not declared @c explicit so initializations can use 0296 assignment syntax @c =. 0297 0298 @b Throws: This can throw in case programmers specify contract failure 0299 handlers that throw exceptions instead of terminating the 0300 program (see 0301 @RefSect{advanced.throw_on_failures__and__noexcept__, 0302 Throw on Failure}). 0303 0304 @param contract Contract to be checked (usually the return value of 0305 @RefFunc{boost::contract::function}, 0306 @RefFunc{boost::contract::constructor}, 0307 @RefFunc{boost::contract::destructor}, or 0308 @RefFunc{boost::contract::public_function}). 0309 0310 @tparam VirtualResult Return type of the enclosing function declaring the 0311 contract if that is either a virtual or an 0312 overriding public function, otherwise this is always 0313 @c void. 0314 (Usually this template parameter is automatically 0315 deduced by C++ and it does not need to be explicitly 0316 specified by programmers.) 0317 */ 0318 /* implicit */ check 0319 /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ( 0320 specify_nothing const& contract) 0321 #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN 0322 BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_nothing) 0323 #else 0324 ; 0325 #endif 0326 0327 /** 0328 Destruct this object. 0329 0330 This checks class invariants at exit and either postconditions when the 0331 enclosing function body did not throw an exception, or exception guarantees 0332 when the function body threw an exception (if class invariants, 0333 postconditions, and exception guarantees respectively were specified for the 0334 enclosing class and the contract parameter given when constructing this 0335 object). 0336 0337 @b Throws: This can throw in case programmers specify contract failure 0338 handlers that throw exceptions instead of terminating the 0339 program (see 0340 @RefSect{advanced.throw_on_failures__and__noexcept__, 0341 Throw on Failure}). 0342 (This is declared @c noexcept(false) since C++11.) 0343 */ 0344 ~check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ () 0345 BOOST_NOEXCEPT_IF(false) /* allow auto_ptr dtor to throw */ 0346 {} 0347 0348 /** @cond */ 0349 private: 0350 check& operator=(check const&); // Cannot copy outside of `check c = ...`. 0351 0352 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ 0353 defined(BOOST_CONTRACT_STATIC_LINK) 0354 boost::contract::detail::auto_ptr<boost::contract::detail::cond_base> 0355 cond_; 0356 #endif 0357 /** @endcond */ 0358 }; 0359 0360 } } // namespace 0361 0362 #endif // #include guard 0363
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|