| 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/** @fileRAII 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, andexception 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 anexception (even if destructors should usually not be programmed to throwexceptions in C++ and they are implicitly declared @c noexcept since C++11).@li Static invariants are always checked at entry and exit (and regardless ofthe body throwing exceptions or not).When used this way, this object is constructed and initialized to the returnvalue 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 whenit 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
 |