diff options
Diffstat (limited to 'boost/contract/detail/operation/destructor.hpp')
-rw-r--r-- | boost/contract/detail/operation/destructor.hpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/boost/contract/detail/operation/destructor.hpp b/boost/contract/detail/operation/destructor.hpp new file mode 100644 index 0000000000..ea8d8780a1 --- /dev/null +++ b/boost/contract/detail/operation/destructor.hpp @@ -0,0 +1,102 @@ + +#ifndef BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_ +#define BOOST_CONTRACT_DETAIL_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 + +#include <boost/contract/core/exception.hpp> +#include <boost/contract/core/config.hpp> +#include <boost/contract/detail/condition/cond_inv.hpp> +#include <boost/contract/detail/none.hpp> +#if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \ + !defined(BOOST_CONTRACT_NO_INVARIANTS) || \ + !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ + !defined(BOOST_CONTRACT_NO_EXCEPTS)) + #include <boost/contract/detail/checking.hpp> +#endif +#if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \ + !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ + !defined(BOOST_CONTRACT_NO_EXCEPTS) + #include <boost/config.hpp> + #include <exception> +#endif + +namespace boost { namespace contract { namespace detail { + +// Dtor subcontracting impl via C++ obj destruction mechanism. +template<class C> // Non-copyable base. +class destructor : public cond_inv</* VR = */ none, C> { +public: + explicit destructor(C* obj) : cond_inv</* VR = */ none, C>( + boost::contract::from_destructor, obj) {} + +private: + #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \ + !defined(BOOST_CONTRACT_NO_OLDS) + void init() /* override */ { + #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION + if(checking::already()) return; + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + { + #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION + checking k; + #endif + // Obj exists (before dtor body), check static and non- inv. + this->check_entry_all_inv(); + // Dtor cannot have pre because it has no parameters. + } + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + this->copy_old(); + #endif + } + #endif + +public: + #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \ + !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ + !defined(BOOST_CONTRACT_NO_EXCEPTS) + ~destructor() BOOST_NOEXCEPT_IF(false) { + this->assert_initialized(); + #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION + if(checking::already()) return; + checking k; + #endif + + // If dtor body threw, obj still exists so check subcontracted + // static and non- inv (but no post because of throw). Otherwise, + // obj destructed so check static inv and post (even if there is no + // obj after dtor body, this library allows dtor post, for example + // to check static members for an instance counter class). + // NOTE: In theory C++ destructors should not throw, but the + // language allows for that (even if in C++11 dtors declarations are + // implicitly noexcept(true) unless specified otherwise) so this + // library must handle such a case. + if(std::uncaught_exception()) { + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + this->check_exit_all_inv(); + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + this->check_except(); + #endif + } else { + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + this->check_exit_static_inv(); + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + this->check_post(none()); + #endif + } + } + #endif +}; + +} } } // namespace + +#endif // #include guard + |