• 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 throw from public function (derived and bases) .pre().
8 
9 #include "../detail/oteststream.hpp"
10 #include <boost/contract/public_function.hpp>
11 #include <boost/contract/assert.hpp>
12 #include <boost/contract/base_types.hpp>
13 #include <boost/contract/override.hpp>
14 #include <boost/contract/check.hpp>
15 #include <boost/detail/lightweight_test.hpp>
16 #include <sstream>
17 
18 boost::contract::test::detail::oteststream out;
19 
20 struct c_err {}; // Global decl so visible in MSVC10 lambdas.
21 
22 struct c {
static_invariantc23     static void static_invariant() { out << "c::static_inv" << std::endl; }
invariantc24     void invariant() const { out << "c::inv" << std::endl; }
25 
fc26     virtual void f(boost::contract::virtual_* v = 0) {
27         boost::contract::check c = boost::contract::public_function(v, this)
28             .precondition([] {
29                 out << "c::f::pre" << std::endl;
30                 BOOST_CONTRACT_ASSERT(false); // To check derived pre.
31             })
32             .old([] { out << "c::f::old" << std::endl; })
33             .postcondition([] { out << "c::f::post" << std::endl; })
34             .except([] { out << "c::f::except" << std::endl; })
35         ;
36         out << "c::f::body" << std::endl;
37     }
38 };
39 
40 struct b_err {}; // Global decl so visible in MSVC10 lambdas.
41 
42 struct b
43     #define BASES public c
44     : BASES
45 {
46     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
47     #undef BASES
48 
static_invariantb49     static void static_invariant() { out << "b::static_inv" << std::endl; }
invariantb50     void invariant() const { out << "b::inv" << std::endl; }
51 
fb52     virtual void f(boost::contract::virtual_* v = 0) /* override */ {
53         boost::contract::check c = boost::contract::public_function<override_f>(
54                 v, &b::f, this)
55             .precondition([] {
56                 out << "b::f::pre" << std::endl;
57                 BOOST_CONTRACT_ASSERT(false); // To check derived pre.
58             })
59             .old([] { out << "b::f::old" << std::endl; })
60             .postcondition([] { out << "b::f::post" << std::endl; })
61             .except([] { out << "b::f::except" << std::endl; })
62         ;
63         out << "b::f::body" << std::endl;
64     }
65     BOOST_CONTRACT_OVERRIDE(f)
66 };
67 
68 struct a_err {}; // Global decl so visible in MSVC10 lambdas.
69 
70 struct a
71     #define BASES 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 
fa80     void f(boost::contract::virtual_* v = 0) /* override */ {
81         boost::contract::check c = boost::contract::public_function<override_f>(
82                 v, &a::f, this)
83             .precondition([] {
84                 out << "a::f::pre" << std::endl;
85                 throw a_err(); // Test this throws.
86             })
87             .old([] { out << "a::f::old" << std::endl; })
88             .postcondition([] { out << "a::f::post" << std::endl; })
89             .except([] { out << "a::f::except" << std::endl; })
90         ;
91         out << "a::f::body" << std::endl;
92     }
93     BOOST_CONTRACT_OVERRIDE(f)
94 };
95 
main()96 int main() {
97     std::ostringstream ok;
98 
99     boost::contract::set_precondition_failure(
100             [] (boost::contract::from) { throw; });
101 
102     a aa;
103     b& ba = aa; // Test as virtual call via polymorphism.
104     try {
105         out.str("");
106         ba.f();
107         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
108                 BOOST_TEST(false);
109             } catch(a_err const&) {
110         #endif
111         ok.str(""); ok
112             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
113                 << "c::static_inv" << std::endl
114                 << "c::inv" << std::endl
115                 << "b::static_inv" << std::endl
116                 << "b::inv" << std::endl
117                 << "a::static_inv" << std::endl
118                 << "a::inv" << std::endl
119             #endif
120             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
121                 << "c::f::pre" << std::endl
122                 << "b::f::pre" << std::endl
123                 << "a::f::pre" << std::endl // Test this threw.
124             #else
125             #ifndef BOOST_CONTRACT_NO_OLDS
126                     << "c::f::old" << std::endl
127                     << "b::f::old" << std::endl
128                     << "a::f::old" << std::endl
129                 #endif
130                 << "a::f::body" << std::endl
131                 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
132                     << "c::static_inv" << std::endl
133                     << "c::inv" << std::endl
134                     << "b::static_inv" << std::endl
135                     << "b::inv" << std::endl
136                     << "a::static_inv" << std::endl
137                     << "a::inv" << std::endl
138                 #endif
139                 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
140                     << "c::f::old" << std::endl
141                     << "c::f::post" << std::endl
142                     << "b::f::old" << std::endl
143                     << "b::f::post" << std::endl
144                     // No old call here because not a base object.
145                     << "a::f::post" << std::endl
146                 #endif
147             #endif
148         ;
149         BOOST_TEST(out.eq(ok.str()));
150     } catch(...) { BOOST_TEST(false); }
151 
152     return boost::report_errors();
153 }
154 
155