2 #ifndef BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_
3 #define BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_
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
10 #include <boost/contract/core/exception.hpp>
11 #include <boost/contract/core/config.hpp>
12 #include <boost/contract/detail/condition/cond_inv.hpp>
13 #include <boost/contract/detail/none.hpp>
14 #if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
15 !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
16 !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
17 !defined(BOOST_CONTRACT_NO_EXCEPTS))
18 #include <boost/contract/detail/checking.hpp>
20 #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
21 !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
22 !defined(BOOST_CONTRACT_NO_EXCEPTS)
23 #include <boost/config.hpp>
27 namespace boost { namespace contract { namespace detail {
29 // Dtor subcontracting impl via C++ obj destruction mechanism.
30 template<class C> // Non-copyable base.
31 class destructor : public cond_inv</* VR = */ none, C> {
33 explicit destructor(C* obj) : cond_inv</* VR = */ none, C>(
34 boost::contract::from_destructor, obj) {}
37 #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
38 !defined(BOOST_CONTRACT_NO_OLDS)
39 void init() /* override */ {
40 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
41 if(checking::already()) return;
44 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
46 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
49 // Obj exists (before dtor body), check static and non- inv.
50 this->check_entry_all_inv();
51 // Dtor cannot have pre because it has no parameters.
54 #ifndef BOOST_CONTRACT_NO_OLDS
61 #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
62 !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
63 !defined(BOOST_CONTRACT_NO_EXCEPTS)
64 ~destructor() BOOST_NOEXCEPT_IF(false) {
65 this->assert_initialized();
66 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
67 if(checking::already()) return;
71 // If dtor body threw, obj still exists so check subcontracted
72 // static and non- inv (but no post because of throw). Otherwise,
73 // obj destructed so check static inv and post (even if there is no
74 // obj after dtor body, this library allows dtor post, for example
75 // to check static members for an instance counter class).
76 // NOTE: In theory C++ destructors should not throw, but the
77 // language allows for that (even if in C++11 dtors declarations are
78 // implicitly noexcept(true) unless specified otherwise) so this
79 // library must handle such a case.
80 if(std::uncaught_exception()) {
81 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
82 this->check_exit_all_inv();
84 #ifndef BOOST_CONTRACT_NO_EXCEPTS
88 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
89 this->check_exit_static_inv();
91 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
92 this->check_post(none());
101 #endif // #include guard