• 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 body (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)
__anonb04dd8730202null34             .old([] { out << "c::ctor::old" << std::endl; })
__anonb04dd8730302null35             .postcondition([] { out << "c::ctor::post" << std::endl; })
__anonb04dd8730402null36             .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)
__anonb04dd8730602null61             .old([] { out << "b::ctor::old" << std::endl; })
__anonb04dd8730702null62             .postcondition([] { out << "b::ctor::post" << std::endl; })
__anonb04dd8730802null63             .except([] { out << "b::ctor::except" << std::endl; })
64         ;
65         out << "b::ctor::body" << std::endl;
66         throw b_err(); // Test body throws (from inheritance mid branch).
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)
__anonb04dd8730a02null86             .old([] { out << "a::ctor::old" << std::endl; })
__anonb04dd8730b02null87             .postcondition([] { out << "a::ctor::post" << std::endl; })
__anonb04dd8730c02null88             .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     try {
99         out.str("");
100         a aa;
101         BOOST_TEST(false);
102     } catch(b_err const&) {
103         ok.str(""); ok
104             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
105                 << "a::ctor::pre" << std::endl
106                 << "b::ctor::pre" << std::endl
107                 << "c::ctor::pre" << std::endl
108             #endif
109 
110             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
111                 << "c::static_inv" << std::endl
112             #endif
113             #ifndef BOOST_CONTRACT_NO_OLDS
114                 << "c::ctor::old" << std::endl
115             #endif
116             << "c::ctor::body" << std::endl
117             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
118                 << "c::static_inv" << std::endl
119                 << "c::inv" << std::endl
120             #endif
121             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
122                 << "c::ctor::post" << std::endl
123             #endif
124 
125             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
126                 << "b::static_inv" << std::endl
127             #endif
128             #ifndef BOOST_CONTRACT_NO_OLDS
129                 << "b::ctor::old" << std::endl
130             #endif
131             << "b::ctor::body" << std::endl // Test this threw...
132             // ... so check only following after (no post, no a ctor, etc.).
133             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
134                 << "b::static_inv" << std::endl
135             #endif
136             #ifndef BOOST_CONTRACT_NO_EXCEPTS
137                 << "b::ctor::except" << std::endl
138             #endif
139         ;
140         BOOST_TEST(out.eq(ok.str()));
141     } catch(...) { BOOST_TEST(false); }
142 
143     return boost::report_errors();
144 }
145 
146