]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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 overrides with mixed access level from (single) base. | |
8 | ||
9 | #include "../detail/oteststream.hpp" | |
10 | #include <boost/contract/public_function.hpp> | |
11 | #include <boost/contract/function.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 b { // Test all access levels (public, protected, and private). | |
21 | friend void call(b& me) { // Test polymorphic calls (object by &). | |
22 | me.f(); | |
23 | me.g(); | |
24 | me.h(); | |
25 | } | |
26 | ||
27 | static void statci_inv() { out << "b::static_inv" << std::endl; } | |
28 | void invariant() const { out << "b::inv" << std::endl; } | |
29 | ||
30 | virtual void f(boost::contract::virtual_* v = 0) { | |
31 | boost::contract::check c = boost::contract::public_function(v, this) | |
32 | .precondition([] { out << "b::f::pre" << std::endl; }) | |
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 | // NOTE: Both protected and private virtual members must declare | |
40 | // extra `virtual_* = 0` parameter (otherwise they cannot be overridden in | |
41 | // derived classes with contracts because C++ uses also default parameters | |
42 | // to match signature of overriding functions). | |
43 | ||
44 | protected: | |
92f5a8d4 | 45 | virtual void g(boost::contract::virtual_* /* v */= 0) { |
11fdf7f2 TL |
46 | boost::contract::check c = boost::contract::function() |
47 | .precondition([] { out << "b::g::pre" << std::endl; }) | |
48 | .old([] { out << "b::g::old" << std::endl; }) | |
49 | .postcondition([] { out << "b::g::post" << std::endl; }) | |
50 | ; | |
51 | out << "b::g::body" << std::endl; | |
52 | } | |
53 | ||
54 | private: | |
92f5a8d4 | 55 | virtual void h(boost::contract::virtual_* /* v */ = 0) { |
11fdf7f2 TL |
56 | boost::contract::check c = boost::contract::function() |
57 | .precondition([] { out << "b::h::pre" << std::endl; }) | |
58 | .old([] { out << "b::h::old" << std::endl; }) | |
59 | .postcondition([] { out << "b::h::post" << std::endl; }) | |
60 | ; | |
61 | out << "b::h::body" << std::endl; | |
62 | } | |
63 | }; | |
64 | ||
65 | struct a // Test overrides with mixed access levels from base. | |
66 | #define BASES public b | |
67 | : BASES | |
68 | { | |
69 | typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; | |
70 | #undef BASES | |
71 | ||
72 | static void statci_inv() { out << "a::static_inv" << std::endl; } | |
73 | void invariant() const { out << "a::inv" << std::endl; } | |
74 | ||
75 | virtual void f(boost::contract::virtual_* v = 0) /* override */ { | |
76 | boost::contract::check c = boost::contract::public_function<override_f>( | |
77 | v, &a::f, this) | |
78 | .precondition([] { out << "a::f::pre" << std::endl; }) | |
79 | .old([] { out << "a::f::old" << std::endl; }) | |
80 | .postcondition([] { out << "a::f::post" << std::endl; }) | |
81 | ; | |
82 | out << "a::f::body" << std::endl; | |
83 | } | |
92f5a8d4 | 84 | BOOST_CONTRACT_OVERRIDES(f) |
11fdf7f2 TL |
85 | |
86 | // Following do not override public members so no `override_...` param and | |
87 | // they do not actually subcontract. | |
88 | ||
89 | virtual void g(boost::contract::virtual_* v = 0) /* override */ { | |
90 | boost::contract::check c = boost::contract::public_function(v, this) | |
91 | .precondition([] { out << "a::g::pre" << std::endl; }) | |
92 | .old([] { out << "a::g::old" << std::endl; }) | |
93 | .postcondition([] { out << "a::g::post" << std::endl; }) | |
94 | ; | |
95 | out << "a::g::body" << std::endl; | |
96 | } | |
97 | ||
98 | virtual void h(boost::contract::virtual_* v = 0) /* override */ { | |
99 | boost::contract::check c = boost::contract::public_function(v, this) | |
100 | .precondition([] { out << "a::h::pre" << std::endl; }) | |
101 | .old([] { out << "a::h::old" << std::endl; }) | |
102 | .postcondition([] { out << "a::h::post" << std::endl; }) | |
103 | ; | |
104 | out << "a::h::body" << std::endl; | |
105 | } | |
106 | }; | |
107 | ||
108 | int main() { | |
109 | std::ostringstream ok; | |
110 | ||
111 | b bb; | |
112 | out.str(""); | |
113 | call(bb); | |
114 | ok.str(""); ok | |
115 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS | |
116 | << "b::inv" << std::endl | |
117 | #endif | |
118 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
119 | << "b::f::pre" << std::endl | |
120 | #endif | |
121 | #ifndef BOOST_CONTRACT_NO_OLDS | |
122 | << "b::f::old" << std::endl | |
123 | #endif | |
124 | << "b::f::body" << std::endl | |
125 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS | |
126 | << "b::inv" << std::endl | |
127 | #endif | |
128 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
129 | << "b::f::post" << std::endl | |
130 | #endif | |
131 | ||
132 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
133 | << "b::g::pre" << std::endl | |
134 | #endif | |
135 | #ifndef BOOST_CONTRACT_NO_OLDS | |
136 | << "b::g::old" << std::endl | |
137 | #endif | |
138 | << "b::g::body" << std::endl | |
139 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
140 | << "b::g::post" << std::endl | |
141 | #endif | |
142 | ||
143 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
144 | << "b::h::pre" << std::endl | |
145 | #endif | |
146 | #ifndef BOOST_CONTRACT_NO_OLDS | |
147 | << "b::h::old" << std::endl | |
148 | #endif | |
149 | << "b::h::body" << std::endl | |
150 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
151 | << "b::h::post" << std::endl | |
152 | #endif | |
153 | ; | |
154 | BOOST_TEST(out.eq(ok.str())); | |
155 | ||
156 | a aa; | |
157 | out.str(""); | |
158 | call(aa); | |
159 | ok.str(""); ok | |
160 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS | |
161 | << "b::inv" << std::endl | |
162 | << "a::inv" << std::endl | |
163 | #endif | |
164 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
165 | << "b::f::pre" << std::endl | |
166 | #endif | |
167 | #ifndef BOOST_CONTRACT_NO_OLDS | |
168 | << "b::f::old" << std::endl | |
169 | << "a::f::old" << std::endl | |
170 | #endif | |
171 | << "a::f::body" << std::endl | |
172 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS | |
173 | << "b::inv" << std::endl | |
174 | << "a::inv" << std::endl | |
175 | #endif | |
176 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
177 | << "b::f::old" << std::endl | |
178 | << "b::f::post" << std::endl | |
179 | << "a::f::post" << std::endl | |
180 | #endif | |
181 | ||
182 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS | |
183 | << "a::inv" << std::endl | |
184 | #endif | |
185 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
186 | << "a::g::pre" << std::endl | |
187 | #endif | |
188 | #ifndef BOOST_CONTRACT_NO_OLDS | |
189 | << "a::g::old" << std::endl | |
190 | #endif | |
191 | << "a::g::body" << std::endl | |
192 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS | |
193 | << "a::inv" << std::endl | |
194 | #endif | |
195 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
196 | << "a::g::post" << std::endl | |
197 | #endif | |
198 | ||
199 | #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS | |
200 | << "a::inv" << std::endl | |
201 | #endif | |
202 | #ifndef BOOST_CONTRACT_NO_PRECONDITIONS | |
203 | << "a::h::pre" << std::endl | |
204 | #endif | |
205 | #ifndef BOOST_CONTRACT_NO_OLDS | |
206 | << "a::h::old" << std::endl | |
207 | #endif | |
208 | << "a::h::body" << std::endl | |
209 | #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS | |
210 | << "a::inv" << std::endl | |
211 | #endif | |
212 | #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS | |
213 | << "a::h::post" << std::endl | |
214 | #endif | |
215 | ; | |
216 | BOOST_TEST(out.eq(ok.str())); | |
217 | ||
218 | return boost::report_errors(); | |
219 | } | |
220 |