• 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 only middle base class with postconditions.
8 
9 #define BOOST_CONTRACT_TEST_NO_A_POST
10 #undef BOOST_CONTRACT_TEST_NO_B_POST
11 #define 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     ;
32     return ok.str();
33 }
34 
ok_b()35 std::string ok_b() {
36     std::ostringstream ok; ok
37         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
38             << "b::static_inv" << std::endl
39             << "b::inv" << std::endl
40         #endif
41         #ifndef BOOST_CONTRACT_NO_OLDS
42             << "b::dtor::old" << std::endl
43         #endif
44         << "b::dtor::body" << std::endl
45         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
46             << "b::static_inv" << std::endl
47         #endif
48         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
49             << "b::dtor::post" << std::endl // This can fail.
50         #endif
51     ;
52     return ok.str();
53 }
54 
ok_c(bool threw=false)55 std::string ok_c(bool threw = false) {
56     std::ostringstream ok; ok
57         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
58             << "c::static_inv" << std::endl
59             << "c::inv" << std::endl
60         #endif
61         #ifndef BOOST_CONTRACT_NO_OLDS
62             << "c::dtor::old" << std::endl
63         #endif
64         << "c::dtor::body" << std::endl
65         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
66             << "c::static_inv" << std::endl
67             << (threw ? "c::inv\n" : "")
68         #endif
69     ;
70     return ok.str();
71 }
72 
73 struct err {}; // Global decl so visible in MSVC10 lambdas.
74 
main()75 int main() {
76     std::ostringstream ok;
77 
78     a_post = true;
79     b_post = true;
80     c_post = true;
81     {
82         a aa;
83         out.str("");
84     }
85     ok.str(""); ok // Test nothing failed.
86         << ok_a()
87         << ok_b()
88         << ok_c()
89     ;
90     BOOST_TEST(out.eq(ok.str()));
91 
92     boost::contract::set_postcondition_failure([&ok] (boost::contract::from) {
93         BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws...
94         throw err(); // ... for testing (as dtors should never throw anyways).
95     });
96 
97     a_post = false;
98     b_post = true;
99     c_post = true;
100     try {
101         {
102             a aa;
103             out.str("");
104         }
105         ok.str(""); ok
106             << ok_a() // Test no a::dtor::post so no failure here.
107             << ok_b()
108             << ok_c()
109         ;
110         BOOST_TEST(out.eq(ok.str()));
111     } catch(...) { BOOST_TEST(false); }
112 
113     #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS
114         #define BOOST_CONTRACT_TEST_post 0
115     #else
116         #define BOOST_CONTRACT_TEST_post 1
117     #endif
118 
119     a_post = true;
120     b_post = false;
121     c_post = true;
122     try {
123         {
124             a aa;
125             ok.str(""); ok
126                 << ok_a()
127                 << ok_b() // Test b::dtor::post failed.
128             ;
129             out.str("");
130         }
131         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
132                 BOOST_TEST(false);
133             } catch(err const&) {
134         #endif
135         ok // ... then exec other dtors and check inv on throw (as dtor threw).
136             << ok_c(BOOST_CONTRACT_TEST_post)
137         ;
138         BOOST_TEST(out.eq(ok.str()));
139     } catch(...) { BOOST_TEST(false); }
140 
141     a_post = true;
142     b_post = true;
143     c_post = false;
144     try {
145         {
146             a aa;
147             out.str("");
148         }
149         ok.str(""); ok
150             << ok_a()
151             << ok_b()
152             << ok_c() // Test no c::dtor::post so no failure here.
153         ;
154         BOOST_TEST(out.eq(ok.str()));
155     } catch(...) { BOOST_TEST(false); }
156 
157     a_post = false;
158     b_post = false;
159     c_post = false;
160     try {
161         {
162             a aa;
163             ok.str(""); ok
164                 << ok_a()
165                 << ok_b() // Test b::dtor::post failed.
166             ;
167             out.str("");
168         }
169         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
170                 BOOST_TEST(false);
171             } catch(err const&) {
172         #endif
173         ok // ... then exec other dtors and check inv on throw (as dtor threw).
174             << ok_c(BOOST_CONTRACT_TEST_post)
175         ;
176         BOOST_TEST(out.eq(ok.str()));
177     } catch(...) { BOOST_TEST(false); }
178 
179     #undef BOOST_CONTRACT_TEST_post
180     return boost::report_errors();
181 }
182 
183