Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:45:02

0001 
0002 #ifndef BOOST_CONTRACT_DESTRUCTOR_HPP_
0003 #define BOOST_CONTRACT_DESTRUCTOR_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 Program contracts for destructors.
0012 */
0013 
0014 #include <boost/contract/core/config.hpp>
0015 #include <boost/contract/core/specify.hpp>
0016 #include <boost/contract/core/access.hpp>
0017 #if     !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \
0018         !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
0019          defined(BOOST_CONTRACT_STATIC_LINK)
0020     #include <boost/contract/detail/operation/destructor.hpp>
0021 #endif
0022 
0023 namespace boost { namespace contract {
0024 
0025 /**
0026 Program contracts for destructors.
0027 
0028 This is used to specify postconditions, exception guarantees, old value copies
0029 at body, and check class invariants for destructors (destructors cannot have
0030 preconditions, see
0031 @RefSect{contract_programming_overview.destructor_calls, Destructor Calls}):
0032 
0033 @code
0034 class u {
0035     friend class boost::contract::access;
0036 
0037     void invariant() const { // Optional (as for static and volatile).
0038         BOOST_CONTRACT_ASSERT(...);
0039         ...
0040     }
0041 
0042 public:
0043     ~u() {
0044         boost::contract::old_ptr<old_type> old_var;
0045         boost::contract::check c = boost::contract::destructor(this)
0046             // No `.precondition` (destructors have no preconditions).
0047             .old([&] { // Optional.
0048                 old_var = BOOST_CONTRACT_OLDOF(old_expr);
0049                 ...
0050             })
0051             .postcondition([&] { // Optional.
0052                 BOOST_CONTRACT_ASSERT(...);
0053                 ...
0054             })
0055             .except([&] { // Optional.
0056                 BOOST_CONTRACT_ASSERT(...);
0057                 ...
0058             })
0059         ;
0060 
0061         ... // Destructor body.
0062     }
0063     
0064     ...
0065 };
0066 @endcode
0067 
0068 For optimization, this can be omitted for destructors that do not have
0069 postconditions and exception guarantees, within classes that have no invariants.
0070 
0071 @see @RefSect{tutorial.destructors, Destructors}
0072 
0073 @param obj  The object @c this from the scope of the enclosing destructor
0074             declaring the contract.
0075             (Destructors check all class invariants, including static and
0076             volatile invariants, see @RefSect{tutorial.class_invariants,
0077             Class Invariants} and
0078             @RefSect{extras.volatile_public_functions,
0079             Volatile Public Functions}).
0080 
0081 @tparam Class   The type of the class containing the destructor declaring the
0082                 contract.
0083                 (Usually this template parameter is automatically deduced by C++
0084                 and it does not need to be explicitly specified by programmers.)
0085 
0086 @return The result of this function must be assigned to a variable of type
0087         @RefClass{boost::contract::check} declared explicitly (i.e., without
0088         using C++11 @c auto declarations) and locally just before the code of
0089         the destructor body (otherwise this library will generate a run-time
0090         error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
0091 */
0092 template<class Class>
0093 specify_old_postcondition_except<> destructor(Class* obj) {
0094     // Must #if also on ..._PRECONDITIONS here because specify_... is generic.
0095     #if     !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \
0096             !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
0097              defined(BOOST_CONTRACT_STATIC_LINK)
0098         return specify_old_postcondition_except<>(
0099                 new boost::contract::detail::destructor<Class>(obj));
0100     #else
0101         return specify_old_postcondition_except<>();
0102     #endif
0103 }
0104 
0105 } } // namespace
0106 
0107 #endif // #include guard
0108