1 2 // Copyright (C) 2008-2018 Lorenzo Caminiti 3 // Distributed under the Boost Software License, Version 1.0 (see accompanying 4 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). 5 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html 6 7 // Test all derived and base classes with postconditions. 8 9 #undef BOOST_CONTRACT_TEST_NO_A_POST 10 #undef BOOST_CONTRACT_TEST_NO_B_POST 11 #undef BOOST_CONTRACT_TEST_NO_C_POST 12 #include "decl.hpp" 13 14 #include <boost/detail/lightweight_test.hpp> 15 #include <sstream> 16 #include <string> 17 ok_a()18std::string ok_a() { 19 std::ostringstream ok; ok 20 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 21 << "a::static_inv" << std::endl 22 << "a::inv" << std::endl 23 #endif 24 #ifndef BOOST_CONTRACT_NO_OLDS 25 << "a::dtor::old" << std::endl 26 #endif 27 << "a::dtor::body" << std::endl 28 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 29 << "a::static_inv" << std::endl 30 #endif 31 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 32 << "a::dtor::post" << std::endl // This can fail. 33 #endif 34 ; 35 return ok.str(); 36 } 37 ok_b(bool threw=false)38std::string ok_b(bool threw = false) { 39 std::ostringstream ok; ok 40 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 41 << "b::static_inv" << std::endl 42 << "b::inv" << std::endl 43 #endif 44 #ifndef BOOST_CONTRACT_NO_OLDS 45 << "b::dtor::old" << std::endl 46 #endif 47 << "b::dtor::body" << std::endl 48 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 49 << "b::static_inv" << std::endl 50 << (threw ? "b::inv\n" : "") 51 #endif 52 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 53 << (!threw ? "b::dtor::post\n" : "") // This can fail. 54 #endif 55 ; 56 return ok.str(); 57 } 58 ok_c(bool threw=false)59std::string ok_c(bool threw = false) { 60 std::ostringstream ok; ok 61 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 62 << "c::static_inv" << std::endl 63 << "c::inv" << std::endl 64 #endif 65 #ifndef BOOST_CONTRACT_NO_OLDS 66 << "c::dtor::old" << std::endl 67 #endif 68 << "c::dtor::body" << std::endl 69 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 70 << "c::static_inv" << std::endl 71 << (threw ? "c::inv\n" : "") 72 #endif 73 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 74 << (!threw ? "c::dtor::post\n" : "") // This can fail. 75 #endif 76 ; 77 return ok.str(); 78 } 79 80 struct err {}; // Global decl so visible in MSVC10 lambdas. 81 main()82int main() { 83 std::ostringstream ok; 84 85 a_post = true; 86 b_post = true; 87 c_post = true; 88 { 89 a aa; 90 out.str(""); 91 } 92 ok.str(""); ok // Test nothing failed. 93 << ok_a() 94 << ok_b() 95 << ok_c() 96 ; 97 BOOST_TEST(out.eq(ok.str())); 98 99 boost::contract::set_postcondition_failure([&ok] (boost::contract::from) { 100 BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... 101 throw err(); // for testing (as dtors should never throw anyways). 102 }); 103 104 #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS 105 #define BOOST_CONTRACT_TEST_post 0 106 #else 107 #define BOOST_CONTRACT_TEST_post 1 108 #endif 109 110 a_post = false; 111 b_post = true; 112 c_post = true; 113 try { 114 { 115 a aa; 116 ok.str(""); ok 117 << ok_a() // Test a::dtor::post failed... 118 ; 119 out.str(""); 120 } 121 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 122 BOOST_TEST(false); 123 } catch(err const&) { 124 #endif 125 ok // ...then exec other dtors and check inv on throw (as dtor threw). 126 << ok_b(BOOST_CONTRACT_TEST_post) 127 << ok_c(BOOST_CONTRACT_TEST_post) 128 ; 129 BOOST_TEST(out.eq(ok.str())); 130 } catch(...) { BOOST_TEST(false); } 131 132 a_post = true; 133 b_post = false; 134 c_post = true; 135 try { 136 { 137 a aa; 138 ok.str(""); ok 139 << ok_a() 140 << ok_b() // Test b::dtor::post failed... 141 ; 142 out.str(""); 143 } 144 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 145 BOOST_TEST(false); 146 } catch(err const&) { 147 #endif 148 ok // ...then exec other dtors and check inv on throw (as dtor threw). 149 << ok_c(BOOST_CONTRACT_TEST_post) 150 ; 151 BOOST_TEST(out.eq(ok.str())); 152 } catch(...) { BOOST_TEST(false); } 153 154 a_post = true; 155 b_post = true; 156 c_post = false; 157 try { 158 { 159 a aa; 160 ok.str(""); ok 161 << ok_a() 162 << ok_b() 163 << ok_c() // Test c::dtor::post failed... 164 ; 165 out.str(""); 166 } 167 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 168 BOOST_TEST(false); 169 } catch(err const&) { 170 #endif 171 // ...then exec other dtors and check inv on throw (as dtor threw). 172 BOOST_TEST(out.eq(ok.str())); 173 } catch(...) { BOOST_TEST(false); } 174 175 a_post = false; 176 b_post = false; 177 c_post = false; 178 try { 179 { 180 a aa; 181 ok.str(""); ok 182 << ok_a() // Test a::dtor::post failed... 183 ; 184 out.str(""); 185 } 186 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 187 BOOST_TEST(false); 188 } catch(err const&) { 189 #endif 190 ok // ...then exec other dtors and check inv on throw (as dtor threw). 191 << ok_b(BOOST_CONTRACT_TEST_post) 192 << ok_c(BOOST_CONTRACT_TEST_post) 193 ; 194 BOOST_TEST(out.eq(ok.str())); 195 } catch(...) { BOOST_TEST(false); } 196 197 #undef BOOST_CONTRACT_TEST_post 198 return boost::report_errors(); 199 } 200 201