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 throw form constructor .pre() (in middle branch of inheritance tree). 8 9 #include "../detail/oteststream.hpp" 10 #include <boost/contract/constructor.hpp> 11 #include <boost/contract/base_types.hpp> 12 #include <boost/contract/check.hpp> 13 #include <boost/detail/lightweight_test.hpp> 14 #include <sstream> 15 16 boost::contract::test::detail::oteststream out; 17 18 struct c 19 #define BASES private boost::contract::constructor_precondition<c> 20 : BASES 21 { 22 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; 23 #undef BASES 24 static_invariantc25 static void static_invariant() { out << "c::static_inv" << std::endl; } invariantc26 void invariant() const { out << "c::inv" << std::endl; } 27 cc28 c() : 29 boost::contract::constructor_precondition<c>([] { 30 out << "c::ctor::pre" << std::endl; 31 }) 32 { 33 boost::contract::check c = boost::contract::constructor(this) __anon09a0488d0202null34 .old([] { out << "c::ctor::old" << std::endl; }) __anon09a0488d0302null35 .postcondition([] { out << "c::ctor::post" << std::endl; }) __anon09a0488d0402null36 .except([] { out << "c::ctor::except" << std::endl; }) 37 ; 38 out << "c::ctor::body" << std::endl; 39 // Do not throw (from inheritance root). 40 } 41 }; 42 43 struct b_err {}; // Global decl so visible in MSVC10 lambdas. 44 45 struct b 46 #define BASES private boost::contract::constructor_precondition<b>, public c 47 : BASES 48 { 49 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; 50 #undef BASES 51 static_invariantb52 static void static_invariant() { out << "b::static_inv" << std::endl; } invariantb53 void invariant() const { out << "b::inv" << std::endl; } 54 bb55 b() : 56 boost::contract::constructor_precondition<b>([] { 57 out << "b::ctor::pre" << std::endl; 58 throw b_err(); // Test this throws (from mid branch). 59 }) 60 { 61 boost::contract::check c = boost::contract::constructor(this) __anon09a0488d0602null62 .old([] { out << "b::ctor::old" << std::endl; }) __anon09a0488d0702null63 .postcondition([] { out << "b::ctor::post" << std::endl; }) __anon09a0488d0802null64 .except([] { out << "b::ctor::except" << std::endl; }) 65 ; 66 out << "b::ctor::body" << std::endl; 67 } 68 }; 69 70 struct a 71 #define BASES private boost::contract::constructor_precondition<a>, public b 72 : BASES 73 { 74 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; 75 #undef BASES 76 static_invarianta77 static void static_invariant() { out << "a::static_inv" << std::endl; } invarianta78 void invariant() const { out << "a::inv" << std::endl; } 79 aa80 a() : 81 boost::contract::constructor_precondition<a>([] { 82 out << "a::ctor::pre" << std::endl; 83 }) 84 { 85 boost::contract::check c = boost::contract::constructor(this) __anon09a0488d0a02null86 .old([] { out << "a::ctor::old" << std::endl; }) __anon09a0488d0b02null87 .postcondition([] { out << "a::ctor::post" << std::endl; }) __anon09a0488d0c02null88 .except([] { out << "a::ctor::except" << std::endl; }) 89 ; 90 out << "a::ctor::body" << std::endl; 91 // Do not throw (from inheritance leaf). 92 } 93 }; 94 main()95int main() { 96 std::ostringstream ok; 97 98 boost::contract::set_precondition_failure( 99 [] (boost::contract::from) { throw; }); 100 101 try { 102 out.str(""); 103 a aa; 104 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 105 BOOST_TEST(false); 106 } catch(b_err const&) { 107 #endif 108 ok.str(""); ok 109 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 110 << "a::ctor::pre" << std::endl 111 << "b::ctor::pre" << std::endl // Test this threw. 112 #else 113 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 114 << "c::static_inv" << std::endl 115 #endif 116 #ifndef BOOST_CONTRACT_NO_OLDS 117 << "c::ctor::old" << std::endl 118 #endif 119 << "c::ctor::body" << std::endl 120 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 121 << "c::static_inv" << std::endl 122 << "c::inv" << std::endl 123 #endif 124 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 125 << "c::ctor::post" << std::endl 126 #endif 127 128 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 129 << "b::static_inv" << std::endl 130 #endif 131 #ifndef BOOST_CONTRACT_NO_OLDS 132 << "b::ctor::old" << std::endl 133 #endif 134 << "b::ctor::body" << std::endl 135 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 136 << "b::static_inv" << std::endl 137 << "b::inv" << std::endl 138 #endif 139 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 140 << "b::ctor::post" << std::endl 141 #endif 142 143 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS 144 << "a::static_inv" << std::endl 145 #endif 146 #ifndef BOOST_CONTRACT_NO_OLDS 147 << "a::ctor::old" << std::endl 148 #endif 149 << "a::ctor::body" << std::endl 150 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS 151 << "a::static_inv" << std::endl 152 << "a::inv" << std::endl 153 #endif 154 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 155 << "a::ctor::post" << std::endl 156 #endif 157 #endif 158 ; 159 BOOST_TEST(out.eq(ok.str())); 160 } catch(...) { BOOST_TEST(false); } 161 162 return boost::report_errors(); 163 } 164 165