• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()18 std::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)38 std::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)59 std::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()82 int 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