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 preconditions.
8 
9 #define BOOST_CONTRACT_TEST_NO_A_PRE
10 #undef BOOST_CONTRACT_TEST_NO_B_PRE
11 #define BOOST_CONTRACT_TEST_NO_C_PRE
12 #include "decl.hpp"
13 
14 #include <boost/detail/lightweight_test.hpp>
15 #include <sstream>
16 #include <string>
17 
ok_begin()18 std::string ok_begin() {
19     std::ostringstream ok; ok << "" // Suppress a warning.
20         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
21             << "c::static_inv" << std::endl
22             << "c::inv" << std::endl
23             << "b::static_inv" << std::endl
24             << "b::inv" << std::endl
25             << "a::static_inv" << std::endl
26             << "a::inv" << std::endl
27         #endif
28     ;
29     return ok.str();
30 }
31 
ok_end()32 std::string ok_end() {
33     std::ostringstream ok; ok
34         #ifndef BOOST_CONTRACT_NO_OLDS
35             << "c::f::old" << std::endl
36             << "b::f::old" << std::endl
37             << "a::f::old" << std::endl
38         #endif
39         << "a::f::body" << std::endl
40         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
41             << "c::static_inv" << std::endl
42             << "c::inv" << std::endl
43             << "b::static_inv" << std::endl
44             << "b::inv" << std::endl
45             << "a::static_inv" << std::endl
46             << "a::inv" << std::endl
47         #endif
48         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
49             << "c::f::old" << std::endl // Old only if post (or except) run.
50             << "c::f::post" << std::endl
51             << "b::f::old" << std::endl
52             << "b::f::post" << std::endl
53             << "a::f::post" << std::endl
54         #endif
55     ;
56     return ok.str();
57 }
58 
59 struct err {}; // Global decl so visible in MSVC10 lambdas.
60 
main()61 int main() {
62     std::ostringstream ok;
63 
64     a aa;
65 
66     a_pre = true;
67     b_pre = true;
68     c_pre = true;
69     out.str("");
70     aa.f();
71     ok.str(""); ok // Test nothing failed.
72         << ok_begin()
73         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
74             << "b::f::pre" << std::endl
75         #endif
76         << ok_end()
77     ;
78     BOOST_TEST(out.eq(ok.str()));
79 
80     a_pre = false;
81     b_pre = true;
82     c_pre = false;
83     out.str("");
84     aa.f();
85     ok.str(""); ok
86         << ok_begin()
87         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
88             // Test only middle pre checked and no fail.
89             << "b::f::pre" << std::endl
90         #endif
91         << ok_end()
92     ;
93     BOOST_TEST(out.eq(ok.str()));
94 
95     boost::contract::set_precondition_failure(
96             [] (boost::contract::from) { throw err(); });
97 
98     a_pre = true;
99     b_pre = false;
100     c_pre = false;
101     out.str("");
102     try {
103         aa.f();
104         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
105                 BOOST_TEST(false);
106             } catch(err const&) {
107         #endif
108         ok.str(""); ok
109             << ok_begin()
110             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
111                 // Test only middle pre checked and failed.
112                 << "b::f::pre" << std::endl
113             #else
114                 << ok_end()
115             #endif
116         ;
117         BOOST_TEST(out.eq(ok.str()));
118     } catch(...) { BOOST_TEST(false); }
119 
120     a_pre = false;
121     b_pre = false;
122     c_pre = true;
123     out.str("");
124     try {
125         aa.f();
126         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
127                 BOOST_TEST(false);
128             } catch(err const&) {
129         #endif
130         ok.str(""); ok
131             << ok_begin()
132             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
133                 // Test only middle pre checked and failed.
134                 << "b::f::pre" << std::endl
135             #else
136                 << ok_end()
137             #endif
138         ;
139         BOOST_TEST(out.eq(ok.str()));
140     } catch(...) { BOOST_TEST(false); }
141 
142     a_pre = false;
143     b_pre = false;
144     c_pre = false;
145     out.str("");
146     try {
147         aa.f();
148         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
149                 BOOST_TEST(false);
150             } catch(err const&) {
151         #endif
152         ok.str(""); ok
153             << ok_begin()
154             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
155                 // Test only middle pre checked and failed.
156                 << "b::f::pre" << std::endl
157             #else
158                 << ok_end()
159             #endif
160         ;
161         BOOST_TEST(out.eq(ok.str()));
162     } catch(...) { BOOST_TEST(false); }
163 
164     return boost::report_errors();
165 }
166 
167