1
2 #ifndef BOOST_CONTRACT_DESTRUCTOR_HPP_
3 #define BOOST_CONTRACT_DESTRUCTOR_HPP_
4
5 // Copyright (C) 2008-2018 Lorenzo Caminiti
6 // Distributed under the Boost Software License, Version 1.0 (see accompanying
7 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
8 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
9
10 /** @file
11 Program contracts for destructors.
12 */
13
14 #include <boost/contract/core/config.hpp>
15 #include <boost/contract/core/specify.hpp>
16 #include <boost/contract/core/access.hpp>
17 #if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \
18 !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
19 defined(BOOST_CONTRACT_STATIC_LINK)
20 #include <boost/contract/detail/operation/destructor.hpp>
21 #endif
22
23 namespace boost { namespace contract {
24
25 /**
26 Program contracts for destructors.
27
28 This is used to specify postconditions, exception guarantees, old value copies
29 at body, and check class invariants for destructors (destructors cannot have
30 preconditions, see
31 @RefSect{contract_programming_overview.destructor_calls, Destructor Calls}):
32
33 @code
34 class u {
35 friend class boost::contract::access;
36
37 void invariant() const { // Optional (as for static and volatile).
38 BOOST_CONTRACT_ASSERT(...);
39 ...
40 }
41
42 public:
43 ~u() {
44 boost::contract::old_ptr<old_type> old_var;
45 boost::contract::check c = boost::contract::destructor(this)
46 // No `.precondition` (destructors have no preconditions).
47 .old([&] { // Optional.
48 old_var = BOOST_CONTRACT_OLDOF(old_expr);
49 ...
50 })
51 .postcondition([&] { // Optional.
52 BOOST_CONTRACT_ASSERT(...);
53 ...
54 })
55 .except([&] { // Optional.
56 BOOST_CONTRACT_ASSERT(...);
57 ...
58 })
59 ;
60
61 ... // Destructor body.
62 }
63
64 ...
65 };
66 @endcode
67
68 For optimization, this can be omitted for destructors that do not have
69 postconditions and exception guarantees, within classes that have no invariants.
70
71 @see @RefSect{tutorial.destructors, Destructors}
72
73 @param obj The object @c this from the scope of the enclosing destructor
74 declaring the contract.
75 (Destructors check all class invariants, including static and
76 volatile invariants, see @RefSect{tutorial.class_invariants,
77 Class Invariants} and
78 @RefSect{extras.volatile_public_functions,
79 Volatile Public Functions}).
80
81 @tparam Class The type of the class containing the destructor declaring the
82 contract.
83 (Usually this template parameter is automatically deduced by C++
84 and it does not need to be explicitly specified by programmers.)
85
86 @return The result of this function must be assigned to a variable of type
87 @RefClass{boost::contract::check} declared explicitly (i.e., without
88 using C++11 @c auto declarations) and locally just before the code of
89 the destructor body (otherwise this library will generate a run-time
90 error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}).
91 */
92 template<class Class>
destructor(Class * obj)93 specify_old_postcondition_except<> destructor(Class* obj) {
94 // Must #if also on ..._PRECONDITIONS here because specify_... is generic.
95 #if !defined(BOOST_CONTRACT_NO_DESTRUCTORS) || \
96 !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
97 defined(BOOST_CONTRACT_STATIC_LINK)
98 return specify_old_postcondition_except<>(
99 new boost::contract::detail::destructor<Class>(obj));
100 #else
101 return specify_old_postcondition_except<>();
102 #endif
103 }
104
105 } } // namespace
106
107 #endif // #include guard
108
109