]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/contract/test/public_function/overload.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / contract / test / public_function / overload.hpp
CommitLineData
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 public function overloads.
8
9#include "../detail/oteststream.hpp"
10#include <boost/contract/public_function.hpp>
11#include <boost/contract/base_types.hpp>
12#include <boost/contract/override.hpp>
13#include <boost/contract/check.hpp>
14#include <boost/detail/lightweight_test.hpp>
15#include <sstream>
16#include <string>
17
18boost::contract::test::detail::oteststream out;
19
20struct b {
21 static void static_invariant() { out << "b::static_inv" << std::endl; }
22 void invariant() const { out << "b::inv" << std::endl; }
23
92f5a8d4 24 virtual void f(int /* x */, boost::contract::virtual_* v = 0) {
11fdf7f2
TL
25 boost::contract::check c = boost::contract::public_function(v, this)
26 .precondition([] { out << "b::f(int)::pre" << std::endl; })
27 .old([] { out << "b::f(int)::old" << std::endl; })
28 .postcondition([] { out << "b::f(int)::post" << std::endl; })
29 ;
30 out << "b::f(int)::body" << std::endl;
31 }
32
92f5a8d4 33 virtual void f(char const* /* x */, boost::contract::virtual_* v = 0) {
11fdf7f2
TL
34 boost::contract::check c = boost::contract::public_function(v, this)
35 .precondition([] { out << "b::f(char const*)::pre" << std::endl; })
36 .old([] { out << "b::f(char const*)::old" << std::endl; })
37 .postcondition(
38 [] { out << "b::f(char const*)::post" << std::endl; })
39 ;
40 out << "b::f(char const*)::body" << std::endl;
41 }
42
92f5a8d4 43 virtual void f(int /* x */, int /* y */, boost::contract::virtual_* v = 0) {
11fdf7f2
TL
44 boost::contract::check c = boost::contract::public_function(v, this)
45 .precondition([] { out << "b::f(int, int)::pre" << std::endl; })
46 .old([] { out << "b::f(int, int)::old" << std::endl; })
47 .postcondition([] { out << "b::f(int, int)::post" << std::endl; })
48 ;
49 out << "b::f(int, int)::body" << std::endl;
50 }
51
52 virtual void f(boost::contract::virtual_* v = 0) {
53 boost::contract::check c = boost::contract::public_function(v, this)
54 .precondition([] { out << "b::f()::pre" << std::endl; })
55 .old([] { out << "b::f()::old" << std::endl; })
56 .postcondition([] { out << "b::f()::post" << std::endl; })
57 ;
58 out << "b::f()::body" << std::endl;
59 }
60
92f5a8d4 61 void f(int /* x */[2][3], boost::contract::virtual_* v = 0) {
11fdf7f2
TL
62 boost::contract::check c = boost::contract::public_function(v, this)
63 .precondition([] { out << "b::f(int[2][3])::pre" << std::endl; })
64 .old([] { out << "b::f(int[2][3])::old" << std::endl; })
65 .postcondition([] { out << "b::f(int[2][3])::post" << std::endl; })
66 ;
67 out << "b::f(int[2][3])::body" << std::endl;
68 }
69
92f5a8d4 70 void f(void (* /* x */)(int), boost::contract::virtual_* v = 0) {
11fdf7f2
TL
71 boost::contract::check c = boost::contract::public_function(v, this)
72 .precondition(
73 [] { out << "b::f(void (*)(int))::pre" << std::endl; })
74 .old(
75 [] { out << "b::f(void (*)(int))::old" << std::endl; })
76 .postcondition(
77 [] { out << "b::f(void (*)(int))::post" << std::endl; })
78 ;
79 out << "b::f(void (*)(int))::body" << std::endl;
80 }
81};
82
83struct a
84 #define BASES public b
85 : BASES
86{
87 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
88 #undef BASES
89
90 static void static_invariant() { out << "a::static_inv" << std::endl; }
91 void invariant() const { out << "a::inv" << std::endl; }
92
93 void f(int x, boost::contract::virtual_* v = 0) /* override */ {
94 boost::contract::check c = boost::contract::public_function<override_f>(
95 v,
96 static_cast<void (a::*)(int, boost::contract::virtual_*)>(&a::f),
97 this, x
98 )
99 .precondition([] { out << "a::f(int)::pre" << std::endl; })
100 .old([] { out << "a::f(int)::old" << std::endl; })
101 .postcondition([] { out << "a::f(int)::post" << std::endl; })
102 ;
103 out << "a::f(int)::body" << std::endl;
104 }
105
106 // Test overload via argument type.
107 void f(char const* x, boost::contract::virtual_* v = 0) /* override */ {
108 boost::contract::check c = boost::contract::public_function<override_f>(
109 v,
110 static_cast<void (a::*)(char const*, boost::contract::virtual_*)>(
111 &a::f),
112 this, x
113 )
114 .precondition([] { out << "a::f(char const*)::pre" << std::endl; })
115 .old([] { out << "a::f(char const*)::old" << std::endl; })
116 .postcondition(
117 [] { out << "a::f(char const*)::post" << std::endl; })
118 ;
119 out << "a::f(char const*)::body" << std::endl;
120 }
121
122 // Test overload via argument count.
123 void f(int x, int y, boost::contract::virtual_* v = 0) /* override */ {
124 boost::contract::check c = boost::contract::public_function<override_f>(
125 v,
126 static_cast<void (a::*)(int, int, boost::contract::virtual_*)>(
127 &a::f),
128 this, x, y
129 )
130 .precondition([] { out << "a::f(int, int)::pre" << std::endl; })
131 .old([] { out << "a::f(int, int)::old" << std::endl; })
132 .postcondition([] { out << "a::f(int, int)::post" << std::endl; })
133 ;
134 out << "a::f(int, int)::body" << std::endl;
135 }
136
137 // Test overload via template argument type.
138 template<typename T>
92f5a8d4 139 void f(T /* x */) { // Template cannot be virtual (or override) in C++.
11fdf7f2
TL
140 boost::contract::check c = boost::contract::public_function(this)
141 .precondition([] { out << "a::f(T)::pre" << std::endl; })
142 .old([] { out << "a::f(T)::old" << std::endl; })
143 .postcondition([] { out << "a::f(T)::post" << std::endl; })
144 ;
145 out << "a::f(T)::body" << std::endl;
146 }
147
148 // Test no overload ambiguity in public_function called by these two cases.
149
150 // NOTE: In *all* other cases, public_function is always called with a
151 // different number of arguments so there cannot be ambiguity either
152 // (0 args for static, 1 arg for non-virtual, 2 or 3 args for virtual,
153 // >= 3 for override, so only in cases below of 3 args for virtual and 3
154 // for override there could be ambiguity but there is not because of
155 // presence or absence of override_... template parameter).
156
157 typedef void (a::* f0_ptr)(boost::contract::virtual_*);
158
159 void f(boost::contract::virtual_* v = 0) /* override */ {
160 f0_ptr f0 = static_cast<f0_ptr>(&a::f);
161 // Test this and public_function call in func below both take same 3
162 // args but they are ambiguous because of presence override_f.
163 boost::contract::check c = boost::contract::public_function<override_f>(
164 v, f0, this)
165 .precondition([] { out << "a::f()::pre" << std::endl; })
166 .old([] { out << "a::f()::old" << std::endl; })
167 .postcondition([] { out << "a::f()::post" << std::endl; })
168 ;
169 out << "a::f()::body" << std::endl;
170 }
171
92f5a8d4 172 virtual f0_ptr f(bool /* x */, boost::contract::virtual_* v = 0)
11fdf7f2
TL
173 /* not an override */ {
174 f0_ptr f0 = static_cast<f0_ptr>(&a::f);
175 // Test this and public_function call in func above both take same 3
176 // args but they are ambiguous because of lack of override_f.
177 boost::contract::check c = boost::contract::public_function(
178 v, f0, this)
179 .precondition([] { out << "a::f(bool)::pre" << std::endl; })
180 .old([] { out << "a::f(bool)::old" << std::endl; })
181 .postcondition([] (f0_ptr const&) {
182 out << "a::f(bool)::post" << std::endl; })
183 ;
184 out << "a::f(bool)::body" << std::endl;
185 return f0;
186 }
187
188 // Test overload with array parameter.
189 void f(int x[2][3], boost::contract::virtual_* v = 0) /* override */ {
190 boost::contract::check c = boost::contract::public_function<override_f>(
191 v,
192 static_cast<void (a::*)(int[2][3], boost::contract::virtual_*)>(
193 &a::f),
194 this, x
195 )
196 .precondition([] { out << "a::f(int[2][3])::pre" << std::endl; })
197 .old([] { out << "a::f(int[2][3])::old" << std::endl; })
198 .postcondition([] { out << "a::f(int[2][3])::post" << std::endl; })
199 ;
200 out << "a::f(int[2][3])::body" << std::endl;
201 }
202
203 // Test overload with function pointer parameter.
204 void f(void (*x)(int), boost::contract::virtual_* v = 0) /* override */ {
205 boost::contract::check c = boost::contract::public_function<override_f>(
206 v,
207 static_cast<void (a::*)(void (*)(int), boost::contract::virtual_*)>(
208 &a::f),
209 this, x
210 )
211 .precondition(
212 [] { out << "a::f(void (*)(int))::pre" << std::endl; })
213 .old(
214 [] { out << "a::f(void (*)(int))::old" << std::endl; })
215 .postcondition(
216 [] { out << "a::f(void (*)(int))::post" << std::endl; })
217 ;
218 out << "a::f(void (*)(int))::body" << std::endl;
219 }
220
221 BOOST_CONTRACT_OVERRIDE(f)
222};
223
224void g(int) {}
225
226std::string ok_args(std::string const& args) {
227 std::ostringstream ok; ok
228 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
229 << "b::static_inv" << std::endl
230 << "b::inv" << std::endl
231 << "a::static_inv" << std::endl
232 << "a::inv" << std::endl
233 #endif
234 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
235 << "b::f(" << args << ")::pre" << std::endl
236 #endif
237 #ifndef BOOST_CONTRACT_NO_OLDS
238 << "b::f(" << args << ")::old" << std::endl
239 << "a::f(" << args << ")::old" << std::endl
240 #endif
241 << "a::f(" << args << ")::body" << std::endl
242 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
243 << "b::static_inv" << std::endl
244 << "b::inv" << std::endl
245 << "a::static_inv" << std::endl
246 << "a::inv" << std::endl
247 #endif
248 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
249 << "b::f(" << args << ")::old" << std::endl
250 << "b::f(" << args << ")::post" << std::endl
251 << "a::f(" << args << ")::post" << std::endl
252 #endif
253 ;
254 return ok.str();
255}
256
257int main() {
258 std::ostringstream ok;
259 a aa;
260
261 out.str("");
262 aa.f(123);
263 ok.str(""); ok << ok_args("int");
264 BOOST_TEST(out.eq(ok.str()));
265
266 out.str("");
267 aa.f("abc");
268 ok.str(""); ok << ok_args("char const*");
269 BOOST_TEST(out.eq(ok.str()));
270
271 out.str("");
272 aa.f(123, 456);
273 ok.str(""); ok << ok_args("int, int");
274 BOOST_TEST(out.eq(ok.str()));
275
276 out.str("");
277 struct {} zz;
278 aa.f(zz); // Call template (so no override because no virtual).
279 ok.str(""); ok
280 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
281 << "a::static_inv" << std::endl
282 << "a::inv" << std::endl
283 #endif
284 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
285 << "a::f(T)::pre" << std::endl
286 #endif
287 #ifndef BOOST_CONTRACT_NO_OLDS
288 << "a::f(T)::old" << std::endl
289 #endif
290 << "a::f(T)::body" << std::endl
291 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
292 << "a::static_inv" << std::endl
293 << "a::inv" << std::endl
294 #endif
295 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
296 << "a::f(T)::post" << std::endl
297 #endif
298 ;
299 BOOST_TEST(out.eq(ok.str()));
300
301 out.str("");
302 aa.f();
303 ok.str(""); ok << ok_args("");
304 BOOST_TEST(out.eq(ok.str()));
305
306 out.str("");
307 aa.f(true); // This does not override (public_function ambiguity testing).
308 ok.str(""); ok
309 #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
310 << "a::static_inv" << std::endl
311 << "a::inv" << std::endl
312 #endif
313 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
314 << "a::f(bool)::pre" << std::endl
315 #endif
316 #ifndef BOOST_CONTRACT_NO_OLDS
317 << "a::f(bool)::old" << std::endl
318 #endif
319 << "a::f(bool)::body" << std::endl
320 #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
321 << "a::static_inv" << std::endl
322 << "a::inv" << std::endl
323 #endif
324 #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
325 << "a::f(bool)::post" << std::endl
326 #endif
327 ;
328 BOOST_TEST(out.eq(ok.str()));
329
330 out.str("");
331 int i[2][3];
332 aa.f(i);
333 ok.str(""); ok << ok_args("int[2][3]");
334 BOOST_TEST(out.eq(ok.str()));
335
336 out.str("");
337 aa.f(&g);
338 ok.str(""); ok << ok_args("void (*)(int)");
339 BOOST_TEST(out.eq(ok.str()));
340
341 return boost::report_errors();
342}
343