• 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 form constructor .post() (in middle branch of inheritance tree).
8 
9 #include "../detail/oteststream.hpp"
10 #include <boost/contract/constructor.hpp>
11 #include <boost/contract/base_types.hpp>
12 #include <boost/contract/check.hpp>
13 #include <boost/detail/lightweight_test.hpp>
14 #include <sstream>
15 
16 boost::contract::test::detail::oteststream out;
17 
18 struct c
19     #define BASES private boost::contract::constructor_precondition<c>
20     : BASES
21 {
22     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
23     #undef BASES
24 
static_invariantc25     static void static_invariant() { out << "c::static_inv" << std::endl; }
invariantc26     void invariant() const { out << "c::inv" << std::endl; }
27 
cc28     c() :
29         boost::contract::constructor_precondition<c>([] {
30             out << "c::ctor::pre" << std::endl;
31         })
32     {
33         boost::contract::check c = boost::contract::constructor(this)
__anon00dc7e4a0202null34             .old([] { out << "c::ctor::old" << std::endl; })
__anon00dc7e4a0302null35             .postcondition([] { out << "c::ctor::post" << std::endl; })
__anon00dc7e4a0402null36             .except([] { out << "c::ctor::except" << std::endl; })
37         ;
38         out << "c::ctor::body" << std::endl;
39         // Do not throw (from inheritance root).
40     }
41 };
42 
43 struct b_err {}; // Global decl so visible in MSVC10 lambdas.
44 
45 struct b
46     #define BASES private boost::contract::constructor_precondition<b>, public c
47     : BASES
48 {
49     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
50     #undef BASES
51 
static_invariantb52     static void static_invariant() { out << "b::static_inv" << std::endl; }
invariantb53     void invariant() const { out << "b::inv" << std::endl; }
54 
bb55     b() :
56         boost::contract::constructor_precondition<b>([] {
57             out << "b::ctor::pre" << std::endl;
58         })
59     {
60         boost::contract::check c = boost::contract::constructor(this)
__anon00dc7e4a0602null61             .old([] { out << "b::ctor::old" << std::endl; })
__anon00dc7e4a0702null62             .postcondition([] {
63                 out << "b::ctor::post" << std::endl;
64                 throw b_err(); // Test this throws (from mid branch).
65             })
__anon00dc7e4a0802null66             .except([] { out << "b::ctor::except" << std::endl; })
67         ;
68         out << "b::ctor::body" << std::endl;
69     }
70 };
71 
72 struct a
73     #define BASES private boost::contract::constructor_precondition<a>, public b
74     : BASES
75 {
76     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
77     #undef BASES
78 
static_invarianta79     static void static_invariant() { out << "a::static_inv" << std::endl; }
invarianta80     void invariant() const { out << "a::inv" << std::endl; }
81 
aa82     a() :
83         boost::contract::constructor_precondition<a>([] {
84             out << "a::ctor::pre" << std::endl;
85         })
86     {
87         boost::contract::check c = boost::contract::constructor(this)
__anon00dc7e4a0a02null88             .old([] { out << "a::ctor::old" << std::endl; })
__anon00dc7e4a0b02null89             .postcondition([] { out << "a::ctor::post" << std::endl; })
__anon00dc7e4a0c02null90             .except([] { out << "a::ctor::except" << std::endl; })
91         ;
92         out << "a::ctor::body" << std::endl;
93         // Do not throw (from inheritance leaf).
94     }
95 };
96 
main()97 int main() {
98     std::ostringstream ok;
99 
100     boost::contract::set_postcondition_failure(
101             [] (boost::contract::from) { throw; });
102 
103     try {
104         out.str("");
105         a aa;
106         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
107                 BOOST_TEST(false);
108             } catch(b_err const&) {
109         #endif
110         ok.str(""); ok
111             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
112                 << "a::ctor::pre" << std::endl
113                 << "b::ctor::pre" << std::endl
114                 << "c::ctor::pre" << std::endl
115             #endif
116 
117             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
118                 << "c::static_inv" << std::endl
119             #endif
120             #ifndef BOOST_CONTRACT_NO_OLDS
121                 << "c::ctor::old" << std::endl
122             #endif
123             << "c::ctor::body" << std::endl
124             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
125                 << "c::static_inv" << std::endl
126                 << "c::inv" << std::endl
127             #endif
128             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
129                 << "c::ctor::post" << std::endl
130             #endif
131 
132             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
133                 << "b::static_inv" << std::endl
134             #endif
135             #ifndef BOOST_CONTRACT_NO_OLDS
136                 << "b::ctor::old" << std::endl
137             #endif
138             << "b::ctor::body" << std::endl
139             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
140                 << "b::static_inv" << std::endl
141                 << "b::inv" << std::endl
142             #endif
143             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
144                 << "b::ctor::post" << std::endl // Test this threw.
145             #else
146                 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
147                     << "a::static_inv" << std::endl
148                 #endif
149                 #ifndef BOOST_CONTRACT_NO_OLDS
150                     << "a::ctor::old" << std::endl
151                 #endif
152                 << "a::ctor::body" << std::endl
153                 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
154                     << "a::static_inv" << std::endl
155                     << "a::inv" << std::endl
156                 #endif
157             #endif
158         ;
159         BOOST_TEST(out.eq(ok.str()));
160     } catch(...) { BOOST_TEST(false); }
161 
162     return boost::report_errors();
163 }
164 
165