Back to home page

EIC code displayed by LXR

 
 

    


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