• 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 making all contract extra declarations (base types, inv, etc.) private.
8 
9 #include "../detail/oteststream.hpp"
10 #include <boost/contract/base_types.hpp>
11 #include <boost/contract/override.hpp>
12 #include <boost/contract/public_function.hpp>
13 #include <boost/contract/check.hpp>
14 #include <boost/contract/assert.hpp>
15 #include <boost/detail/lightweight_test.hpp>
16 #include <sstream>
17 
18 boost::contract::test::detail::oteststream out;
19 
20 class b {
21     friend class boost::contract::access;
22 
static_invariant()23     static void static_invariant() { out << "b::static_inv" << std::endl; }
invariant() const24     void invariant() const { out << "b::inv" << std::endl; }
25 
26 public:
f(char ch,boost::contract::virtual_ * v=0)27     virtual void f(char ch, boost::contract::virtual_* v = 0) {
28         boost::contract::check c = boost::contract::public_function(v, this)
29             .precondition([&] {
30                 out << "b::f::pre" << std::endl;
31                 BOOST_CONTRACT_ASSERT(ch == 'b');
32             })
33             .old([] { out << "b::f::old" << std::endl; })
34             .postcondition([] { out << "b::f::post" << std::endl; })
35         ;
36         out << "b::f::body" << std::endl;
37     }
38 };
39 
40 class a
41     #define BASES public b
42     : BASES
43 {
44     friend class boost::contract::access;
45 
46     // Private base types.
47     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
48     #undef BASES
49 
50     // Private invariants.
static_invariant()51     static void static_invariant() { out << "a::static_inv" << std::endl; }
invariant() const52     void invariant() const { out << "a::inv" << std::endl; }
53 
54     // Private override (always possible even when access is not friend).
55     BOOST_CONTRACT_OVERRIDE(f)
56 
57 public:
f(char ch,boost::contract::virtual_ * v=0)58     virtual void f(char ch, boost::contract::virtual_* v = 0) /* override */ {
59         boost::contract::check c = boost::contract::public_function<override_f>(
60                 v, &a::f, this, ch)
61             .precondition([&] {
62                 out << "a::f::pre" << std::endl;
63                 BOOST_CONTRACT_ASSERT(ch == 'a');
64             })
65             .old([] { out << "a::f::old" << std::endl; })
66             .postcondition([] { out << "a::f::post" << std::endl; })
67         ;
68         out << "a::f::body" << std::endl;
69     }
70 };
71 
main()72 int main() {
73     std::ostringstream ok;
74 
75     a aa;
76     out.str("");
77     aa.f('a');
78     ok.str(""); ok
79         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
80             << "b::static_inv" << std::endl
81             << "b::inv" << std::endl
82             << "a::static_inv" << std::endl
83             << "a::inv" << std::endl
84         #endif
85         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
86             << "b::f::pre" << std::endl
87             << "a::f::pre" << std::endl
88         #endif
89         #ifndef BOOST_CONTRACT_NO_OLDS
90             << "b::f::old" << std::endl
91             << "a::f::old" << std::endl
92         #endif
93         << "a::f::body" << std::endl
94         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
95             << "b::static_inv" << std::endl
96             << "b::inv" << std::endl
97             << "a::static_inv" << std::endl
98             << "a::inv" << std::endl
99         #endif
100         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
101             << "b::f::old" << std::endl
102             << "b::f::post" << std::endl
103             // No old call here because not a base object.
104             << "a::f::post" << std::endl
105         #endif
106     ;
107     BOOST_TEST(out.eq(ok.str()));
108 
109     b bb;
110     out.str("");
111     bb.f('b');
112     ok.str(""); ok
113         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
114             << "b::static_inv" << std::endl
115             << "b::inv" << std::endl
116         #endif
117         #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
118             << "b::f::pre" << std::endl
119         #endif
120         #ifndef BOOST_CONTRACT_NO_OLDS
121             << "b::f::old" << std::endl
122         #endif
123         << "b::f::body" << std::endl
124         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
125             << "b::static_inv" << std::endl
126             << "b::inv" << std::endl
127         #endif
128         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
129             << "b::f::post" << std::endl
130         #endif
131     ;
132     BOOST_TEST(out.eq(ok.str()));
133 
134     return boost::report_errors();
135 }
136 
137