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

source code of boost/libs/contract/test/destructor/decl_entry_static_inv_all.cpp