#ifndef BOOST_CONTRACT_DESTRUCTOR_HPP_ #define BOOST_CONTRACT_DESTRUCTOR_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 Program contracts for destructors. */ #include #include #include #if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #include #endif namespace boost { namespace contract { /** Program contracts for destructors. This is used to specify postconditions, exception guarantees, old value copies at body, and check class invariants for destructors (destructors cannot have preconditions, see @RefSect{contract_programming_overview.destructor_calls, Destructor Calls}): @code class u { friend class boost::contract::access; void invariant() const { // Optional (as for static and volatile). BOOST_CONTRACT_ASSERT(...); ... } public: ~u() { boost::contract::old_ptr old_var; boost::contract::check c = boost::contract::destructor(this) // No `.precondition` (destructors have no preconditions). .old([&] { // Optional. old_var = BOOST_CONTRACT_OLDOF(old_expr); ... }) .postcondition([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) .except([&] { // Optional. BOOST_CONTRACT_ASSERT(...); ... }) ; ... // Destructor body. } ... }; @endcode For optimization, this can be omitted for destructors that do not have postconditions and exception guarantees, within classes that have no invariants. @see @RefSect{tutorial.destructors, Destructors} @param obj The object @c this from the scope of the enclosing destructor declaring the contract. (Destructors check all class invariants, including static and volatile invariants, see @RefSect{tutorial.class_invariants, Class Invariants} and @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @tparam Class The type of the class containing the destructor declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @return The result of this function must be assigned to a variable of type @RefClass{boost::contract::check} declared explicitly (i.e., without using C++11 @c auto declarations) and locally just before the code of the destructor body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template specify_old_postcondition_except<> destructor(Class* obj) { // Must #if also on ..._PRECONDITIONS here because specify_... is generic. #if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \ !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) return specify_old_postcondition_except<>( new boost::contract::detail::destructor(obj)); #else return specify_old_postcondition_except<>(); #endif } } } // namespace #endif // #include guard