constructor.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #ifndef BOOST_CONTRACT_DETAIL_CONSTRUCTOR_HPP_
  2. #define BOOST_CONTRACT_DETAIL_CONSTRUCTOR_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. #if !defined(BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION) && ( \
  12. !defined(BOOST_CONTRACT_NO_INVARIANTS) || \
  13. !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
  14. !defined(BOOST_CONTRACT_NO_EXCEPTS))
  15. #include <boost/contract/detail/checking.hpp>
  16. #endif
  17. #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
  18. !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
  19. !defined(BOOST_CONTRACT_NO_EXCEPTS)
  20. #include <boost/config.hpp>
  21. #include <exception>
  22. #endif
  23. namespace boost { namespace contract { namespace detail {
  24. // Ctor subcontracting impl via C++ obj construction mechanism.
  25. template<class C> // Non-copyable base.
  26. class constructor : public cond_inv</* VR = */ none, C> {
  27. public:
  28. explicit constructor(C* obj) : cond_inv</* VR = */ none, C>(
  29. boost::contract::from_constructor, obj) {}
  30. private:
  31. #if !defined(BOOST_CONTRACT_NO_ENTRY_INVARIANTS) || \
  32. !defined(BOOST_CONTRACT_NO_OLDS)
  33. void init() /* override */ {
  34. #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
  35. if(checking::already()) return;
  36. #endif
  37. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  38. {
  39. #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
  40. checking k;
  41. #endif
  42. this->check_entry_static_inv();
  43. // No object before ctor body so check only static inv at
  44. // entry. Ctor pre checked by constructor_precondition.
  45. }
  46. #endif
  47. #ifndef BOOST_CONTRACT_NO_OLDS
  48. this->copy_old();
  49. #endif
  50. }
  51. #endif
  52. public:
  53. #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \
  54. !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \
  55. !defined(BOOST_CONTRACT_NO_EXCEPTS)
  56. ~constructor() BOOST_NOEXCEPT_IF(false) {
  57. this->assert_initialized();
  58. #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION
  59. if(checking::already()) return;
  60. checking k;
  61. #endif
  62. // If ctor body threw, no obj so check only static inv. Otherwise,
  63. // obj constructed so check static inv, non-static inv, and post.
  64. if(std::uncaught_exception()) {
  65. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  66. this->check_exit_static_inv();
  67. #endif
  68. #ifndef BOOST_CONTRACT_NO_EXCEPTS
  69. this->check_except();
  70. #endif
  71. } else {
  72. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  73. this->check_exit_all_inv();
  74. #endif
  75. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  76. this->check_post(none());
  77. #endif
  78. }
  79. }
  80. #endif
  81. };
  82. } } } // namespace
  83. #endif // #include guard