]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | |
2 | #ifndef BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_ | |
3 | #define BOOST_CONTRACT_DETAIL_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 | #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> | |
92f5a8d4 | 14 | #include <boost/contract/detail/exception.hpp> |
11fdf7f2 TL |
15 | #if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \ |
16 | !defined(BOOST_CONTRACT_NO_INVARIANTS) || \ | |
17 | !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ | |
18 | !defined(BOOST_CONTRACT_NO_EXCEPTS)) | |
19 | #include <boost/contract/detail/checking.hpp> | |
20 | #endif | |
21 | #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \ | |
22 | !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ | |
23 | !defined(BOOST_CONTRACT_NO_EXCEPTS) | |
24 | #include <boost/config.hpp> | |
25 | #include <exception> | |
26 | #endif | |
27 | ||
28 | namespace boost { namespace contract { namespace detail { | |
29 | ||
30 | // Dtor subcontracting impl via C++ obj destruction mechanism. | |
31 | template<class C> // Non-copyable base. | |
32 | class destructor : public cond_inv</* VR = */ none, C> { | |
33 | public: | |
34 | explicit destructor(C* obj) : cond_inv</* VR = */ none, C>( | |
35 | boost::contract::from_destructor, obj) {} | |
36 | ||
37 | private: | |
38 | #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \ | |
39 | !defined(BOOST_CONTRACT_NO_OLDS) | |
40 | void init() /* override */ { | |
41 | #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION | |
42 | if(checking::already()) return; | |
43 | #endif | |
44 | ||
45 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS | |
46 | { | |
47 | #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION | |
48 | checking k; | |
49 | #endif | |
50 | // Obj exists (before dtor body), check static and non- inv. | |
51 | this->check_entry_all_inv(); | |
52 | // Dtor cannot have pre because it has no parameters. | |
53 | } | |
54 | #endif | |
55 | #ifndef BOOST_CONTRACT_NO_OLDS | |
56 | this->copy_old(); | |
57 | #endif | |
58 | } | |
59 | #endif | |
60 | ||
61 | public: | |
62 | #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \ | |
63 | !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ | |
64 | !defined(BOOST_CONTRACT_NO_EXCEPTS) | |
65 | ~destructor() BOOST_NOEXCEPT_IF(false) { | |
66 | this->assert_initialized(); | |
67 | #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION | |
68 | if(checking::already()) return; | |
69 | checking k; | |
70 | #endif | |
71 | ||
72 | // If dtor body threw, obj still exists so check subcontracted | |
73 | // static and non- inv (but no post because of throw). Otherwise, | |
74 | // obj destructed so check static inv and post (even if there is no | |
75 | // obj after dtor body, this library allows dtor post, for example | |
76 | // to check static members for an instance counter class). | |
77 | // NOTE: In theory C++ destructors should not throw, but the | |
78 | // language allows for that (even if in C++11 dtors declarations are | |
79 | // implicitly noexcept(true) unless specified otherwise) so this | |
80 | // library must handle such a case. | |
92f5a8d4 | 81 | if(uncaught_exception()) { |
11fdf7f2 TL |
82 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS |
83 | this->check_exit_all_inv(); | |
84 | #endif | |
85 | #ifndef BOOST_CONTRACT_NO_EXCEPTS | |
86 | this->check_except(); | |
87 | #endif | |
88 | } else { | |
89 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS | |
90 | this->check_exit_static_inv(); | |
91 | #endif | |
92 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
93 | this->check_post(none()); | |
94 | #endif | |
95 | } | |
96 | } | |
97 | #endif | |
98 | }; | |
99 | ||
100 | } } } // namespace | |
101 | ||
102 | #endif // #include guard | |
103 |