123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- #ifndef BOOST_CONTRACT_CHECK_HPP_
- #define BOOST_CONTRACT_CHECK_HPP_
- // Copyright (C) 2008-2018 Lorenzo Caminiti
- // Distributed under the Boost Software License, Version 1.0 (see accompanying
- // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
- // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
- /** @file
- RAII object that checks contracts.
- */
- #include <boost/contract/core/config.hpp>
- #include <boost/contract/core/check_macro.hpp>
- #include <boost/contract/core/specify.hpp>
- #include <boost/contract/core/exception.hpp> // For set_... (if always in code).
- #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
- defined(BOOST_CONTRACT_STATIC_LINK)
- #include <boost/contract/detail/condition/cond_base.hpp>
- #include <boost/contract/detail/auto_ptr.hpp>
- #include <boost/contract/detail/debug.hpp>
- #endif
- #include <boost/contract/detail/check.hpp>
- #include <boost/config.hpp>
- /* PRIVATE */
- /** @cond */
- #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
- defined(BOOST_CONTRACT_STATIC_LINK)
- #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) \
- : cond_(const_cast<contract_type&>(contract).cond_.release()) \
- { \
- BOOST_CONTRACT_DETAIL_DEBUG(cond_); \
- cond_->initialize(); \
- }
- #else
- #define BOOST_CONTRACT_CHECK_CTOR_DEF_(contract_type) {}
- #endif
- /** @endcond */
- /* CODE */
- namespace boost { namespace contract {
- /**
- RAII object that checks the contracts.
- In general, when this object is constructed it checks class invariants at entry,
- preconditions, and makes old value copies at body.
- When it is destructed, it checks class invariants at exist, postconditions, and
- exception guarantees.
- This object enforces the following (see
- @RefSect{contract_programming_overview, Contract Programming Overview}):
- @li Postconditions are checked only if the body does not throw an exception.
- @li Exceptions guarantees are checked only if the body throws an exception.
- @li Constructor entry never checks class invariants.
- @li Destructor exit checks class invariants only if the body throws an
- exception (even if destructors should usually not be programmed to throw
- exceptions in C++ and they are implicitly declared @c noexcept since C++11).
- @li Static invariants are always checked at entry and exit (and regardless of
- the body throwing exceptions or not).
- When used this way, this object is constructed and initialized to the return
- value of one of the contract functions @RefFunc{boost::contract::function},
- @RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor},
- or @RefFunc{boost::contract::public_function}.
- In addition to that, this object can be constructed from a nullary functor when
- it is used to program implementation checks.
- @see @RefSect{tutorial, Tutorial},
- @RefSect{advanced.implementation_checks, Implementation Checks}
- */
- class check { // Copy ctor only (as move via ptr release).
- public:
- // NOTE: Unfortunately, Apple compilers define a `check(...)` macro that
- // clashes with the name of this class. In the following code,
- // BOOST_PREVENT_MACRO_SUBSTITUTION is used to workaround these name
- // clashes. In user code, `check c = ...` syntax is typically used also
- // avoiding clashes.
- /**
- Construct this object for implementation checks.
- This can be used to program checks within implementation code (body, etc.).
- This constructor is not declared @c explicit so initializations can use
- assignment syntax @c =.
-
- @b Throws: This can throw in case programmers specify contract failure
- handlers that throw exceptions instead of terminating the
- program (see
- @RefSect{advanced.throw_on_failures__and__noexcept__,
- Throw on Failure}).
- @param f Nullary functor that asserts implementation checks. @c f() will
- be called as soon as this object is constructed at the point it
- is declared within the implementation code (see
- @RefSect{advanced.implementation_checks,
- Implementation Checks}).
- */
- template<typename F> // Cannot check `if(f) ...` as f can be a lambda.
- // f must be a valid callable object (not null func ptr, empty ftor, etc.
- /* implicit */ check
- /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
- F const& f) {
- BOOST_CONTRACT_DETAIL_CHECK({ f(); })
- }
- /**
- Construct this object copying it from the specified one.
- This object will check the contract, the copied-from object will not (i.e.,
- contract check ownership is transferred from the copied object to the new
- object being created by this constructor).
- @param other Copied-from object.
- */
- check /** @cond **/ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
- check const& other)
- #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
- defined(BOOST_CONTRACT_STATIC_LINK)
- // Copy ctor moves cond_ pointer to dest.
- : cond_(const_cast<check&>(other).cond_.release())
- #endif
- {}
- /**
- Construct this object to check the specified contract.
- This checks class invariants at entry (if those were specified for the given
- contract).
- This constructor is not declared @c explicit so initializations can use
- assignment syntax @c =.
-
- @b Throws: This can throw in case programmers specify contract failure
- handlers that throw exceptions instead of terminating the
- program (see
- @RefSect{advanced.throw_on_failures__and__noexcept__,
- Throw on Failure}).
- @param contract Contract to be checked (usually the return value of
- @RefFunc{boost::contract::function} or
- @RefFunc{boost::contract::public_function}).
- @tparam VirtualResult Return type of the enclosing function declaring the
- contract if that is either a virtual or an
- overriding public function, otherwise this is always
- @c void.
- (Usually this template parameter is automatically
- deduced by C++ and it does not need to be explicitly
- specified by programmers.)
- */
- template<typename VirtualResult>
- /* implicit */ check
- /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
- specify_precondition_old_postcondition_except<VirtualResult> const&
- contract
- )
- #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
- BOOST_CONTRACT_CHECK_CTOR_DEF_(
- specify_precondition_old_postcondition_except<VirtualResult>)
- #else
- ;
- #endif
-
- /**
- Construct this object to check the specified contract.
- This checks class invariants at entry and preconditions (if any of those
- were specified for the given contract).
- This constructor is not declared @c explicit so initializations can use
- assignment syntax @c =.
-
- @b Throws: This can throw in case programmers specify contract failure
- handlers that throw exceptions instead of terminating the
- program (see
- @RefSect{advanced.throw_on_failures__and__noexcept__,
- Throw on Failure}).
- @param contract Contract to be checked (usually the return value of
- @RefFunc{boost::contract::function},
- @RefFunc{boost::contract::constructor},
- @RefFunc{boost::contract::destructor}, or
- @RefFunc{boost::contract::public_function}).
- @tparam VirtualResult Return type of the enclosing function declaring the
- contract if that is either a virtual or an
- overriding public function, otherwise this is always
- @c void.
- (Usually this template parameter is automatically
- deduced by C++ and it does not need to be explicitly
- specified by programmers.)
- */
- template<typename VirtualResult>
- /* implicit */ check
- /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
- specify_old_postcondition_except<VirtualResult> const& contract)
- #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
- BOOST_CONTRACT_CHECK_CTOR_DEF_(
- specify_old_postcondition_except<VirtualResult>)
- #else
- ;
- #endif
-
- /**
- Construct this object to check the specified contract.
- This checks class invariants at entry and preconditions then it makes old
- value copies at body (if any of those were specified for the given
- contract).
- This constructor is not declared @c explicit so initializations can use
- assignment syntax @c =.
-
- @b Throws: This can throw in case programmers specify contract failure
- handlers that throw exceptions instead of terminating te
- program (see
- @RefSect{advanced.throw_on_failures__and__noexcept__,
- Throw on Failure}).
- @param contract Contract to be checked (usually the return value of
- @RefFunc{boost::contract::function},
- @RefFunc{boost::contract::constructor},
- @RefFunc{boost::contract::destructor}, or
- @RefFunc{boost::contract::public_function}).
- @tparam VirtualResult Return type of the enclosing function declaring the
- contract if that is either a virtual or an
- overriding public function, otherwise this is always
- @c void.
- (Usually this template parameter is automatically
- deduced by C++ and it does not need to be explicitly
- specified by programmers.)
- */
- template<typename VirtualResult>
- /* implicit */ check
- /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
- specify_postcondition_except<VirtualResult> const& contract)
- #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
- BOOST_CONTRACT_CHECK_CTOR_DEF_(
- specify_postcondition_except<VirtualResult>)
- #else
- ;
- #endif
-
- /**
- Construct this object to check the specified contract.
- This checks class invariants at entry and preconditions then it makes old
- value copies at body, plus the destructor of this object will also check
- postconditions in this case (if any of those were specified for the given
- contract).
- This constructor is not declared @c explicit so initializations can use
- assignment syntax @c =.
-
- @b Throws: This can throw in case programmers specify contract failure
- handlers that throw exceptions instead of terminating the
- program (see
- @RefSect{advanced.throw_on_failures__and__noexcept__,
- Throw on Failure}).
- @param contract Contract to be checked (usually the return value of
- @RefFunc{boost::contract::function},
- @RefFunc{boost::contract::constructor},
- @RefFunc{boost::contract::destructor}, or
- @RefFunc{boost::contract::public_function}).
- @tparam VirtualResult Return type of the enclosing function declaring the
- contract if that is either a virtual or an
- overriding public function, otherwise this is always
- @c void.
- (Usually this template parameter is automatically
- deduced by C++ and it does not need to be explicitly
- specified by programmers.)
- */
- /* implicit */ check
- /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
- specify_except const& contract)
- #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
- BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_except)
- #else
- ;
- #endif
-
- /**
- Construct this object to check the specified contract.
- This checks class invariants at entry and preconditions then it makes old
- value copies at body, plus the destructor of this object will also check
- postconditions and exception guarantees in this case (if any of those were
- specified for the given contract).
- This constructor is not declared @c explicit so initializations can use
- assignment syntax @c =.
-
- @b Throws: This can throw in case programmers specify contract failure
- handlers that throw exceptions instead of terminating the
- program (see
- @RefSect{advanced.throw_on_failures__and__noexcept__,
- Throw on Failure}).
- @param contract Contract to be checked (usually the return value of
- @RefFunc{boost::contract::function},
- @RefFunc{boost::contract::constructor},
- @RefFunc{boost::contract::destructor}, or
- @RefFunc{boost::contract::public_function}).
- @tparam VirtualResult Return type of the enclosing function declaring the
- contract if that is either a virtual or an
- overriding public function, otherwise this is always
- @c void.
- (Usually this template parameter is automatically
- deduced by C++ and it does not need to be explicitly
- specified by programmers.)
- */
- /* implicit */ check
- /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ (
- specify_nothing const& contract)
- #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
- BOOST_CONTRACT_CHECK_CTOR_DEF_(specify_nothing)
- #else
- ;
- #endif
- /**
- Destruct this object.
- This checks class invariants at exit and either postconditions when the
- enclosing function body did not throw an exception, or exception guarantees
- when the function body threw an exception (if class invariants,
- postconditions, and exception guarantees respectively were specified for the
- enclosing class and the contract parameter given when constructing this
- object).
- @b Throws: This can throw in case programmers specify contract failure
- handlers that throw exceptions instead of terminating the
- program (see
- @RefSect{advanced.throw_on_failures__and__noexcept__,
- Throw on Failure}).
- (This is declared @c noexcept(false) since C++11.)
- */
- ~check /** @cond */ BOOST_PREVENT_MACRO_SUBSTITUTION /** @endcond */ ()
- BOOST_NOEXCEPT_IF(false) /* allow auto_ptr dtor to throw */
- {}
- /** @cond */
- private:
- check& operator=(check const&); // Cannot copy outside of `check c = ...`.
- #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
- defined(BOOST_CONTRACT_STATIC_LINK)
- boost::contract::detail::auto_ptr<boost::contract::detail::cond_base>
- cond_;
- #endif
- /** @endcond */
- };
- } } // namespace
- #endif // #include guard
|