throwing_body_virtual_branch.cpp 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright (C) 2008-2018 Lorenzo Caminiti
  2. // Distributed under the Boost Software License, Version 1.0 (see accompanying
  3. // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
  4. // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
  5. // Test virt pub func body throws with subcontr from middle of inheritance tree.
  6. #include "smoke.hpp"
  7. #include <boost/optional.hpp>
  8. #include <boost/preprocessor/control/iif.hpp>
  9. #include <boost/detail/lightweight_test.hpp>
  10. #include <sstream>
  11. int main() {
  12. std::ostringstream ok;
  13. c cc; // Test call to class at mid- inheritance tree (as base with bases).
  14. s_type s; s.value = "X"; // So body will throw.
  15. out.str("");
  16. boost::optional<result_type&> r;
  17. try {
  18. r = cc.f(s);
  19. BOOST_TEST(false);
  20. } catch(except_error const&) {
  21. ok.str(""); ok
  22. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  23. << "d::static_inv" << std::endl
  24. << "d::inv" << std::endl
  25. << "e::static_inv" << std::endl
  26. << "e::inv" << std::endl
  27. << "c::static_inv" << std::endl
  28. << "c::inv" << std::endl
  29. #endif
  30. #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
  31. << "d::f::pre" << std::endl
  32. #endif
  33. #ifndef BOOST_CONTRACT_NO_OLDS
  34. << "d::f::old" << std::endl
  35. << "e::f::old" << std::endl
  36. << "c::f::old" << std::endl
  37. #endif
  38. << "c::f::body" << std::endl
  39. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  40. << "d::static_inv" << std::endl
  41. << "d::inv" << std::endl
  42. << "e::static_inv" << std::endl
  43. << "e::inv" << std::endl
  44. << "c::static_inv" << std::endl
  45. << "c::inv" << std::endl
  46. #endif
  47. #ifndef BOOST_CONTRACT_NO_EXCEPTS
  48. << "d::f::old" << std::endl
  49. << "d::f::except" << std::endl
  50. << "e::f::old" << std::endl
  51. << "e::f::except" << std::endl
  52. // No old call here because not a base object.
  53. << "c::f::except" << std::endl
  54. #endif
  55. ;
  56. BOOST_TEST(out.eq(ok.str()));
  57. #ifndef BOOST_CONTRACT_NO_OLDS
  58. #define BOOST_CONTRACT_TEST_old 1u
  59. #else
  60. #define BOOST_CONTRACT_TEST_old 0u
  61. #endif
  62. BOOST_TEST(!r); // Boost.Optional result not init (as body threw).
  63. BOOST_TEST_EQ(s.value, "X");
  64. BOOST_TEST_EQ(s.copies(), BOOST_CONTRACT_TEST_old * 3);
  65. BOOST_TEST_EQ(s.evals(), BOOST_CONTRACT_TEST_old * 3);
  66. BOOST_TEST_EQ(s.ctors(), s.dtors() + 1); // 1 for local var.
  67. BOOST_TEST_EQ(cc.y.value, "c");
  68. BOOST_TEST_EQ(cc.y.copies(), BOOST_CONTRACT_TEST_old);
  69. BOOST_TEST_EQ(cc.y.evals(), BOOST_CONTRACT_TEST_old);
  70. BOOST_TEST_EQ(cc.y.ctors(), cc.y.dtors() + 1); // 1 for member var.
  71. BOOST_TEST_EQ(cc.t<'d'>::z.value, "d");
  72. BOOST_TEST_EQ(cc.t<'d'>::z.copies(), BOOST_CONTRACT_TEST_old);
  73. BOOST_TEST_EQ(cc.t<'d'>::z.evals(), BOOST_CONTRACT_TEST_old);
  74. BOOST_TEST_EQ(cc.t<'d'>::z.ctors(), cc.t<'d'>::z.dtors() + 1); // 1 mem.
  75. BOOST_TEST_EQ(cc.t<'e'>::z.value, "e");
  76. BOOST_TEST_EQ(cc.t<'e'>::z.copies(), BOOST_CONTRACT_TEST_old);
  77. BOOST_TEST_EQ(cc.t<'e'>::z.evals(), BOOST_CONTRACT_TEST_old);
  78. BOOST_TEST_EQ(cc.t<'e'>::z.ctors(), cc.t<'e'>::z.dtors() + 1); // 1 mem.
  79. #undef BOOST_CONTRACT_TEST_old
  80. }
  81. return boost::report_errors();
  82. }