• 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 .pre() (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)
__anon09a0488d0202null34             .old([] { out << "c::ctor::old" << std::endl; })
__anon09a0488d0302null35             .postcondition([] { out << "c::ctor::post" << std::endl; })
__anon09a0488d0402null36             .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             throw b_err(); // Test this throws (from mid branch).
59         })
60     {
61         boost::contract::check c = boost::contract::constructor(this)
__anon09a0488d0602null62             .old([] { out << "b::ctor::old" << std::endl; })
__anon09a0488d0702null63             .postcondition([] { out << "b::ctor::post" << std::endl; })
__anon09a0488d0802null64             .except([] { out << "b::ctor::except" << std::endl; })
65         ;
66         out << "b::ctor::body" << std::endl;
67     }
68 };
69 
70 struct a
71     #define BASES private boost::contract::constructor_precondition<a>, 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 
aa80     a() :
81         boost::contract::constructor_precondition<a>([] {
82             out << "a::ctor::pre" << std::endl;
83         })
84     {
85         boost::contract::check c = boost::contract::constructor(this)
__anon09a0488d0a02null86             .old([] { out << "a::ctor::old" << std::endl; })
__anon09a0488d0b02null87             .postcondition([] { out << "a::ctor::post" << std::endl; })
__anon09a0488d0c02null88             .except([] { out << "a::ctor::except" << std::endl; })
89         ;
90         out << "a::ctor::body" << std::endl;
91         // Do not throw (from inheritance leaf).
92     }
93 };
94 
main()95 int main() {
96     std::ostringstream ok;
97 
98     boost::contract::set_precondition_failure(
99             [] (boost::contract::from) { throw; });
100 
101     try {
102         out.str("");
103         a aa;
104 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
105         BOOST_TEST(false);
106     } catch(b_err const&) {
107 #endif
108         ok.str(""); ok
109             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
110                 << "a::ctor::pre" << std::endl
111                 << "b::ctor::pre" << std::endl // Test this threw.
112             #else
113                 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
114                     << "c::static_inv" << std::endl
115                 #endif
116                 #ifndef BOOST_CONTRACT_NO_OLDS
117                     << "c::ctor::old" << std::endl
118                 #endif
119                 << "c::ctor::body" << std::endl
120                 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
121                     << "c::static_inv" << std::endl
122                     << "c::inv" << std::endl
123                 #endif
124                 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
125                     << "c::ctor::post" << std::endl
126                 #endif
127 
128                 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
129                     << "b::static_inv" << std::endl
130                 #endif
131                 #ifndef BOOST_CONTRACT_NO_OLDS
132                     << "b::ctor::old" << std::endl
133                 #endif
134                 << "b::ctor::body" << std::endl
135                 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
136                     << "b::static_inv" << std::endl
137                     << "b::inv" << std::endl
138                 #endif
139                 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
140                     << "b::ctor::post" << std::endl
141                 #endif
142 
143                 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
144                     << "a::static_inv" << std::endl
145                 #endif
146                 #ifndef BOOST_CONTRACT_NO_OLDS
147                     << "a::ctor::old" << std::endl
148                 #endif
149                 << "a::ctor::body" << std::endl
150                 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
151                     << "a::static_inv" << std::endl
152                     << "a::inv" << std::endl
153                 #endif
154                 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
155                     << "a::ctor::post" << 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