destructor.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #ifndef BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_
  2. #define BOOST_CONTRACT_DETAIL_DESTRUCTOR_HPP_
  3. // Copyright (C) 2008-2018 Lorenzo Caminiti
  4. // Distributed under the Boost Software License, Version 1.0 (see accompanying
  5. // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
  6. // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
  7. #include <boost/contract/core/exception.hpp>
  8. #include <boost/contract/core/config.hpp>
  9. #include <boost/contract/detail/condition/cond_inv.hpp>
  10. #include <boost/contract/detail/none.hpp>
  11. #include <boost/contract/detail/exception.hpp>
  12. #if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
  13. !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
  14. !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
  15. !defined(BOOST_CONTRACT_NO_EXCEPTS))
  16. #include <boost/contract/detail/checking.hpp>
  17. #endif
  18. #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
  19. !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
  20. !defined(BOOST_CONTRACT_NO_EXCEPTS)
  21. #include <boost/config.hpp>
  22. #include <exception>
  23. #endif
  24. namespace boost { namespace contract { namespace detail {
  25. // Dtor subcontracting impl via C++ obj destruction mechanism.
  26. template<class C> // Non-copyable base.
  27. class destructor : public cond_inv</* VR = */ none, C> {
  28. public:
  29. explicit destructor(C* obj) : cond_inv</* VR = */ none, C>(
  30. boost::contract::from_destructor, obj) {}
  31. private:
  32. #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
  33. !defined(BOOST_CONTRACT_NO_OLDS)
  34. void init() /* override */ {
  35. #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
  36. if(checking::already()) return;
  37. #endif
  38. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  39. {
  40. #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
  41. checking k;
  42. #endif
  43. // Obj exists (before dtor body), check static and non- inv.
  44. this->check_entry_all_inv();
  45. // Dtor cannot have pre because it has no parameters.
  46. }
  47. #endif
  48. #ifndef BOOST_CONTRACT_NO_OLDS
  49. this->copy_old();
  50. #endif
  51. }
  52. #endif
  53. public:
  54. #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
  55. !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
  56. !defined(BOOST_CONTRACT_NO_EXCEPTS)
  57. ~destructor() BOOST_NOEXCEPT_IF(false) {
  58. this->assert_initialized();
  59. #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
  60. if(checking::already()) return;
  61. checking k;
  62. #endif
  63. // If dtor body threw, obj still exists so check subcontracted
  64. // static and non- inv (but no post because of throw). Otherwise,
  65. // obj destructed so check static inv and post (even if there is no
  66. // obj after dtor body, this library allows dtor post, for example
  67. // to check static members for an instance counter class).
  68. // NOTE: In theory C++ destructors should not throw, but the
  69. // language allows for that (even if in C++11 dtors declarations are
  70. // implicitly noexcept(true) unless specified otherwise) so this
  71. // library must handle such a case.
  72. if(uncaught_exception()) {
  73. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  74. this->check_exit_all_inv();
  75. #endif
  76. #ifndef BOOST_CONTRACT_NO_EXCEPTS
  77. this->check_except();
  78. #endif
  79. } else {
  80. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  81. this->check_exit_static_inv();
  82. #endif
  83. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  84. this->check_post(none());
  85. #endif
  86. }
  87. }
  88. #endif
  89. };
  90. } } } // namespace
  91. #endif // #include guard