decl_entry_static_inv_all.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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 all derived and base classes with entry static invariants.
  6. #undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV
  7. #undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV
  8. #undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV
  9. #include "decl.hpp"
  10. #include <boost/preprocessor/control/iif.hpp>
  11. #include <boost/detail/lightweight_test.hpp>
  12. #include <sstream>
  13. #include <string>
  14. std::string ok_a() {
  15. std::ostringstream ok; ok
  16. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  17. << "a::static_inv" << std::endl
  18. << "a::inv" << std::endl
  19. #endif
  20. #ifndef BOOST_CONTRACT_NO_OLDS
  21. << "a::dtor::old" << std::endl
  22. #endif
  23. << "a::dtor::body" << std::endl
  24. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  25. << "a::static_inv" << std::endl
  26. #endif
  27. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  28. << "a::dtor::post" << std::endl
  29. #endif
  30. ;
  31. return ok.str();
  32. }
  33. std::string ok_b(bool threw = false) {
  34. std::ostringstream ok; ok
  35. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  36. << "b::static_inv" << std::endl
  37. << "b::inv" << std::endl
  38. #endif
  39. #ifndef BOOST_CONTRACT_NO_OLDS
  40. << "b::dtor::old" << std::endl
  41. #endif
  42. << "b::dtor::body" << std::endl
  43. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  44. << "b::static_inv" << std::endl
  45. << (threw ? "b::inv\n" : "")
  46. #endif
  47. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  48. << (!threw ? "b::dtor::post\n" : "")
  49. #endif
  50. ;
  51. return ok.str();
  52. }
  53. std::string ok_c(bool threw = false) {
  54. std::ostringstream ok; ok
  55. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  56. << "c::static_inv" << std::endl
  57. << "c::inv" << std::endl
  58. #endif
  59. #ifndef BOOST_CONTRACT_NO_OLDS
  60. << "c::dtor::old" << std::endl
  61. #endif
  62. << "c::dtor::body" << std::endl
  63. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  64. << "c::static_inv" << std::endl
  65. << (threw ? "c::inv\n" : "")
  66. #endif
  67. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  68. << (!threw ? "c::dtor::post\n" : "")
  69. #endif
  70. ;
  71. return ok.str();
  72. }
  73. struct err {}; // Global decl so visible in MSVC10 lambdas.
  74. int main() {
  75. std::ostringstream ok;
  76. #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  77. #define BOOST_CONTRACT_TEST_entry_inv 0
  78. #else
  79. #define BOOST_CONTRACT_TEST_entry_inv 1
  80. #endif
  81. a_entry_static_inv = true;
  82. b_entry_static_inv = true;
  83. c_entry_static_inv = true;
  84. a_entering_static_inv = b_entering_static_inv = c_entering_static_inv =
  85. BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false);
  86. {
  87. a aa;
  88. out.str("");
  89. }
  90. ok.str(""); ok // Test nothing failed.
  91. << ok_a()
  92. << ok_b()
  93. << ok_c()
  94. ;
  95. BOOST_TEST(out.eq(ok.str()));
  96. boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) {
  97. BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws.
  98. throw err(); // For testing only (dtors should never throw otherwise).
  99. });
  100. a_entry_static_inv = false;
  101. b_entry_static_inv = true;
  102. c_entry_static_inv = true;
  103. a_entering_static_inv = b_entering_static_inv = c_entering_static_inv =
  104. BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false);
  105. try {
  106. {
  107. a aa;
  108. ok.str(""); ok
  109. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  110. << "a::static_inv" << std::endl // Test this failed...
  111. #else
  112. << ok_a()
  113. #endif
  114. ;
  115. out.str("");
  116. }
  117. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  118. BOOST_TEST(false);
  119. } catch(err const&) {
  120. #endif
  121. ok // ...then exec other dtors and check inv on throw (as dtor threw).
  122. << ok_b(BOOST_CONTRACT_TEST_entry_inv)
  123. << ok_c(BOOST_CONTRACT_TEST_entry_inv)
  124. ;
  125. BOOST_TEST(out.eq(ok.str()));
  126. } catch(...) { BOOST_TEST(false); }
  127. a_entry_static_inv = true;
  128. b_entry_static_inv = false;
  129. c_entry_static_inv = true;
  130. a_entering_static_inv = b_entering_static_inv = c_entering_static_inv =
  131. BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false);
  132. try {
  133. {
  134. a aa;
  135. ok.str(""); ok
  136. << ok_a()
  137. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  138. << "b::static_inv" << std::endl // Test this failed...
  139. #else
  140. << ok_b()
  141. #endif
  142. ;
  143. out.str("");
  144. }
  145. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  146. BOOST_TEST(false);
  147. } catch(err const&) {
  148. #endif
  149. ok // ...then exec other dtors and check inv on throw (as dtor threw).
  150. << ok_c(BOOST_CONTRACT_TEST_entry_inv)
  151. ;
  152. BOOST_TEST(out.eq(ok.str()));
  153. } catch(...) { BOOST_TEST(false); }
  154. a_entry_static_inv = true;
  155. b_entry_static_inv = true;
  156. c_entry_static_inv = false;
  157. a_entering_static_inv = b_entering_static_inv = c_entering_static_inv =
  158. BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false);
  159. try {
  160. {
  161. a aa;
  162. ok.str(""); ok
  163. << ok_a()
  164. << ok_b()
  165. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  166. << "c::static_inv" << std::endl // Test this failed...
  167. #else
  168. << ok_c()
  169. #endif
  170. ;
  171. out.str("");
  172. }
  173. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  174. BOOST_TEST(false);
  175. } catch(err const&) {
  176. #endif
  177. // ...then exec other dtors and check inv on throw (as dtor threw).
  178. BOOST_TEST(out.eq(ok.str()));
  179. } catch(...) { BOOST_TEST(false); }
  180. boost::contract::set_entry_invariant_failure([] (boost::contract::from) {
  181. // Testing multiple failures so dtors must not throw multiple
  182. // exceptions, just ignore failure and continue test program...
  183. });
  184. a_entry_static_inv = false;
  185. b_entry_static_inv = false;
  186. c_entry_static_inv = false;
  187. a_entering_static_inv = b_entering_static_inv = c_entering_static_inv =
  188. BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false);
  189. {
  190. a aa;
  191. out.str("");
  192. }
  193. ok.str(""); ok
  194. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  195. << "a::static_inv" << std::endl // Test this failed (as all did)...
  196. << "a::dtor::body" << std::endl
  197. << "b::static_inv" << std::endl // Test this failed (as all did)...
  198. << "b::dtor::body" << std::endl
  199. << "c::static_inv" << std::endl // Test this failed (as all did)...
  200. << "c::dtor::body" << std::endl
  201. #else
  202. << ok_a()
  203. << ok_b()
  204. << ok_c()
  205. #endif
  206. ;
  207. BOOST_TEST(out.eq(ok.str()));
  208. #undef BOOST_CONTRACT_TEST_entry_inv
  209. return boost::report_errors();
  210. }