• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // no #include guard
3 
4 // Copyright (C) 2008-2018 Lorenzo Caminiti
5 // Distributed under the Boost Software License, Version 1.0 (see accompanying
6 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
7 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
8 
9 // Test with and without all invariants (static/cv/const-only) declarations.
10 
11 #include "../detail/oteststream.hpp"
12 #include <boost/contract/base_types.hpp>
13 #include <boost/contract/constructor.hpp>
14 #include <boost/contract/destructor.hpp>
15 #include <boost/contract/public_function.hpp>
16 #include <boost/contract/function.hpp>
17 #include <boost/contract/override.hpp>
18 #include <boost/contract/check.hpp>
19 #include <boost/contract/assert.hpp>
20 #include <boost/detail/lightweight_test.hpp>
21 #include <sstream>
22 
23 boost::contract::test::detail::oteststream out;
24 
25 struct b : private boost::contract::constructor_precondition<b> {
26     // Test also with no base_types.
27 
28     #ifdef BOOST_CONTRACT_TEST_STATIC_INV
static_invariantb29         static void static_invariant() { out << "b::static_inv" << std::endl; }
30     #endif
31     #ifdef BOOST_CONTRACT_TEST_CV_INV
invariantb32         void invariant() const volatile { out << "b::cv_inv" << std::endl; }
33     #endif
34     #ifdef BOOST_CONTRACT_TEST_CONST_INV
invariantb35         void invariant() const { out << "b::const_inv" << std::endl; }
36     #endif
37 
bb38     b() : boost::contract::constructor_precondition<b>([] {
39         out << "b::ctor::pre" << std::endl;
40     }) {
41         boost::contract::check c = boost::contract::constructor(this)
__anon70508e770202null42             .old([] { out << "b::ctor::old" << std::endl; })
__anon70508e770302null43             .postcondition([] { out << "b::ctor::post" << std::endl; })
44         ;
45         out << "b::ctor::body" << std::endl;
46     }
47 
~bb48     virtual ~b() {
49         boost::contract::check c = boost::contract::destructor(this)
50             .old([] { out << "b::dtor::old" << std::endl; })
51             .postcondition([] { out << "b::dtor::post" << std::endl; })
52         ;
53         out << "b::dtor::body" << std::endl;
54     }
55 
fb56     virtual void f(char x, boost::contract::virtual_* v = 0) volatile {
57         boost::contract::check c = boost::contract::public_function(v, this)
58             .precondition([&] {
59                 out << "b::f::volatile_pre" << std::endl;
60                 BOOST_CONTRACT_ASSERT(x == 'b');
61             })
62             .old([] { out << "b::f::volatile_old" << std::endl; })
63             .postcondition([] { out << "b::f::volatile_post" << std::endl; })
64         ;
65         out << "b::f::volatile_body" << std::endl;
66     }
67 
fb68     virtual void f(char x, boost::contract::virtual_* v = 0) {
69         boost::contract::check c = boost::contract::public_function(v, this)
70             .precondition([&] {
71                 out << "b::f::pre" << std::endl;
72                 BOOST_CONTRACT_ASSERT(x == 'b');
73             })
74             .old([] { out << "b::f::old" << std::endl; })
75             .postcondition([] { out << "b::f::post" << std::endl; })
76         ;
77         out << "b::f::body" << std::endl;
78     }
79 };
80 
81 struct a
82     #define BASES private boost::contract::constructor_precondition<a>, public b
83     : BASES
84 {
85     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
86     #undef BASES
87 
88     #ifdef BOOST_CONTRACT_TEST_STATIC_INV
static_invarianta89         static void static_invariant() { out << "a::static_inv" << std::endl; }
90     #endif
91     #ifdef BOOST_CONTRACT_TEST_CV_INV
invarianta92         void invariant() const volatile { out << "a::cv_inv" << std::endl; }
93     #endif
94     #ifdef BOOST_CONTRACT_TEST_CONST_INV
invarianta95         void invariant() const { out << "a::const_inv" << std::endl; }
96     #endif
97 
aa98     a() : boost::contract::constructor_precondition<a>([] {
99         out << "a::ctor::pre" << std::endl;
100     }) {
101         boost::contract::check c = boost::contract::constructor(this)
__anon70508e770d02null102             .old([] { out << "a::ctor::old" << std::endl; })
__anon70508e770e02null103             .postcondition([] { out << "a::ctor::post" << std::endl; })
104         ;
105         out << "a::ctor::body" << std::endl;
106     }
107 
~aa108     virtual ~a() {
109         boost::contract::check c = boost::contract::destructor(this)
110             .old([] { out << "a::dtor::old" << std::endl; })
111             .postcondition([] { out << "a::dtor::post" << std::endl; })
112         ;
113         out << "a::dtor::body" << std::endl;
114     }
115 
fa116     virtual void f(char x, boost::contract::virtual_* v = 0)
117             volatile /* override */ {
118         boost::contract::check c = boost::contract::public_function<
119                 override_f>(
120             v,
121             static_cast<void (a::*)(char x, boost::contract::virtual_*)
122                     volatile>(&a::f),
123             this, x
124         )
125             .precondition([&] {
126                 out << "a::f::volatile_pre" << std::endl;
127                 BOOST_CONTRACT_ASSERT(x == 'a');
128             })
129             .old([] { out << "a::f::volatile_old" << std::endl; })
130             .postcondition([] { out << "a::f::volatile_post" << std::endl; })
131         ;
132         out << "a::f::volatile_body" << std::endl;
133     }
134 
fa135     virtual void f(char x, boost::contract::virtual_* v = 0) /* override */ {
136         boost::contract::check c = boost::contract::public_function<
137                 override_f>(
138             v,
139             static_cast<void (a::*)(char x, boost::contract::virtual_*)>(&a::f),
140             this, x
141         )
142             .precondition([&] {
143                 out << "a::f::pre" << std::endl;
144                 BOOST_CONTRACT_ASSERT(x == 'a');
145             })
146             .old([] { out << "a::f::old" << std::endl; })
147             .postcondition([] { out << "a::f::post" << std::endl; })
148         ;
149         out << "a::f::body" << std::endl;
150     }
151 
sa152     static void s() {
153         boost::contract::check c = boost::contract::public_function<a>()
154             .precondition([] { out << "a::s::pre" << std::endl; })
155             .old([] { out << "a::s::old" << std::endl; })
156             .postcondition([] { out << "a::s::post" << std::endl; })
157         ;
158         out << "a::s::body" << std::endl;
159     }
160 
161 protected:
pa162     void p() volatile {
163         boost::contract::check c = boost::contract::function()
164             .precondition([] { out << "a::p::volatile_pre" << std::endl; })
165             .old([] { out << "a::p::volatile_old" << std::endl; })
166             .postcondition([] { out << "a::p::volatile_post" << std::endl; })
167         ;
168         out << "a::p::volatile_body" << std::endl;
169     }
170 
pa171     void p() {
172         boost::contract::check c = boost::contract::function()
173             .precondition([] { out << "a::p::pre" << std::endl; })
174             .old([] { out << "a::p::old" << std::endl; })
175             .postcondition([] { out << "a::p::post" << std::endl; })
176         ;
177         out << "a::p::body" << std::endl;
178     }
179 public:
call_pa180     void call_p() volatile { p(); }
call_pa181     void call_p() { p(); }
182 
183 private:
qa184     void q() volatile {
185         boost::contract::check c = boost::contract::function()
186             .precondition([] { out << "a::q::volatile_pre" << std::endl; })
187             .old([] { out << "a::q::volatile_old" << std::endl; })
188             .postcondition([] { out << "a::q::volatile_post" << std::endl; })
189         ;
190         out << "a::q::volatile_body" << std::endl;
191     }
192 
qa193     void q() {
194         boost::contract::check c = boost::contract::function()
195             .precondition([] { out << "a::q::pre" << std::endl; })
196             .old([] { out << "a::q::old" << std::endl; })
197             .postcondition([] { out << "a::q::post" << std::endl; })
198         ;
199         out << "a::q::body" << std::endl;
200     }
201 public:
call_qa202     void call_q() volatile { q(); }
call_qa203     void call_q() { q(); }
204 
205     BOOST_CONTRACT_OVERRIDE(f)
206 };
207 
main()208 int main() {
209     std::ostringstream ok;
210 
211     { // Test volatile call with bases.
212         out.str("");
213         a volatile av;
214         ok.str(""); ok // Ctors always check const_inv (even if volatile).
215             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
216                 << "a::ctor::pre" << std::endl
217                 << "b::ctor::pre" << std::endl
218             #endif
219 
220             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
221                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
222                     << "b::static_inv" << std::endl
223                 #endif
224             #endif
225             #ifndef BOOST_CONTRACT_NO_OLDS
226                 << "b::ctor::old" << std::endl
227             #endif
228             << "b::ctor::body" << std::endl
229             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
230                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
231                     << "b::static_inv" << std::endl
232                 #endif
233                 #ifdef BOOST_CONTRACT_TEST_CV_INV
234                     << "b::cv_inv" << std::endl
235                 #endif
236                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
237                     << "b::const_inv" << std::endl
238                 #endif
239             #endif
240             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
241                 << "b::ctor::post" << std::endl
242             #endif
243 
244             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
245                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
246                     << "a::static_inv" << std::endl
247                 #endif
248             #endif
249             #ifndef BOOST_CONTRACT_NO_OLDS
250                 << "a::ctor::old" << std::endl
251             #endif
252             << "a::ctor::body" << std::endl
253             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
254                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
255                     << "a::static_inv" << std::endl
256                 #endif
257                 #ifdef BOOST_CONTRACT_TEST_CV_INV
258                     << "a::cv_inv" << std::endl
259                 #endif
260                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
261                     << "a::const_inv" << std::endl
262                 #endif
263             #endif
264             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
265                 << "a::ctor::post" << std::endl
266             #endif
267         ;
268         BOOST_TEST(out.eq(ok.str()));
269 
270         out.str("");
271         av.f('a');
272         ok.str(""); ok // Volatile checks static and cv (but not const) inv.
273             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
274                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
275                     << "b::static_inv" << std::endl
276                 #endif
277                 #ifdef BOOST_CONTRACT_TEST_CV_INV
278                     << "b::cv_inv" << std::endl
279                 #endif
280                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
281                     << "a::static_inv" << std::endl
282                 #endif
283                 #ifdef BOOST_CONTRACT_TEST_CV_INV
284                     << "a::cv_inv" << std::endl
285                 #endif
286             #endif
287             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
288                 << "b::f::volatile_pre" << std::endl
289                 << "a::f::volatile_pre" << std::endl
290             #endif
291             #ifndef BOOST_CONTRACT_NO_OLDS
292                 << "b::f::volatile_old" << std::endl
293                 << "a::f::volatile_old" << std::endl
294             #endif
295             << "a::f::volatile_body" << std::endl
296             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
297                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
298                     << "b::static_inv" << std::endl
299                 #endif
300                 #ifdef BOOST_CONTRACT_TEST_CV_INV
301                     << "b::cv_inv" << std::endl
302                 #endif
303                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
304                     << "a::static_inv" << std::endl
305                 #endif
306                 #ifdef BOOST_CONTRACT_TEST_CV_INV
307                     << "a::cv_inv" << std::endl
308                 #endif
309             #endif
310             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
311                 << "b::f::volatile_old" << std::endl
312                 << "b::f::volatile_post" << std::endl
313                 << "a::f::volatile_post" << std::endl
314             #endif
315         ;
316         BOOST_TEST(out.eq(ok.str()));
317 
318         out.str("");
319         av.s(); // Test static call.
320         ok.str(""); ok
321             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
322                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
323                     << "a::static_inv" << std::endl
324                 #endif
325             #endif
326             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
327                 << "a::s::pre" << std::endl
328             #endif
329             #ifndef BOOST_CONTRACT_NO_OLDS
330                 << "a::s::old" << std::endl
331             #endif
332             << "a::s::body" << std::endl
333             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
334                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
335                     << "a::static_inv" << std::endl
336                 #endif
337             #endif
338             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
339                 << "a::s::post" << std::endl
340             #endif
341         ;
342         BOOST_TEST(out.eq(ok.str()));
343 
344         out.str("");
345         av.call_p(); // Test (indirect) protected call.
346         ok.str(""); ok
347             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
348                 << "a::p::volatile_pre" << std::endl
349             #endif
350             #ifndef BOOST_CONTRACT_NO_OLDS
351                 << "a::p::volatile_old" << std::endl
352             #endif
353             << "a::p::volatile_body" << std::endl
354             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
355                 << "a::p::volatile_post" << std::endl
356             #endif
357         ;
358         BOOST_TEST(out.eq(ok.str()));
359 
360         out.str("");
361         av.call_q(); // Test (indirect) private call.
362         ok.str(""); ok
363             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
364                 << "a::q::volatile_pre" << std::endl
365             #endif
366             #ifndef BOOST_CONTRACT_NO_OLDS
367                 << "a::q::volatile_old" << std::endl
368             #endif
369             << "a::q::volatile_body" << std::endl
370             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
371                 << "a::q::volatile_post" << std::endl
372             #endif
373         ;
374         BOOST_TEST(out.eq(ok.str()));
375 
376         out.str("");
377     } // Call a's destructor.
378     ok.str(""); ok // Dtors always check const_inv (even if volatile).
379         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
380             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
381                 << "a::static_inv" << std::endl
382             #endif
383             #ifdef BOOST_CONTRACT_TEST_CV_INV
384                 << "a::cv_inv" << std::endl
385             #endif
386             #ifdef BOOST_CONTRACT_TEST_CONST_INV
387                 << "a::const_inv" << std::endl
388             #endif
389         #endif
390         #ifndef BOOST_CONTRACT_NO_OLDS
391             << "a::dtor::old" << std::endl
392         #endif
393         << "a::dtor::body" << std::endl
394         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
395             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
396                 << "a::static_inv" << std::endl
397             #endif
398         #endif
399         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
400             << "a::dtor::post" << std::endl
401         #endif
402 
403         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
404             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
405                 << "b::static_inv" << std::endl
406             #endif
407             #ifdef BOOST_CONTRACT_TEST_CV_INV
408                 << "b::cv_inv" << std::endl
409             #endif
410             #ifdef BOOST_CONTRACT_TEST_CONST_INV
411                 << "b::const_inv" << std::endl
412             #endif
413         #endif
414         #ifndef BOOST_CONTRACT_NO_OLDS
415             << "b::dtor::old" << std::endl
416         #endif
417         << "b::dtor::body" << std::endl
418         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
419             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
420                 << "b::static_inv" << std::endl
421             #endif
422         #endif
423         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
424             << "b::dtor::post" << std::endl
425         #endif
426     ;
427     BOOST_TEST(out.eq(ok.str()));
428 
429     { // Test non-volatile call with bases.
430         out.str("");
431         a aa;
432         ok.str(""); ok // Ctors always check cv_inv (even if not volatile).
433             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
434                 << "a::ctor::pre" << std::endl
435                 << "b::ctor::pre" << std::endl
436             #endif
437 
438             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
439                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
440                     << "b::static_inv" << std::endl
441                 #endif
442             #endif
443             #ifndef BOOST_CONTRACT_NO_OLDS
444                 << "b::ctor::old" << std::endl
445             #endif
446             << "b::ctor::body" << std::endl
447             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
448                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
449                     << "b::static_inv" << std::endl
450                 #endif
451                 #ifdef BOOST_CONTRACT_TEST_CV_INV
452                     << "b::cv_inv" << std::endl
453                 #endif
454                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
455                     << "b::const_inv" << std::endl
456                 #endif
457             #endif
458             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
459                 << "b::ctor::post" << std::endl
460             #endif
461 
462             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
463                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
464                     << "a::static_inv" << std::endl
465                 #endif
466             #endif
467             #ifndef BOOST_CONTRACT_NO_OLDS
468                 << "a::ctor::old" << std::endl
469             #endif
470             << "a::ctor::body" << std::endl
471             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
472                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
473                     << "a::static_inv" << std::endl
474                 #endif
475                 #ifdef BOOST_CONTRACT_TEST_CV_INV
476                     << "a::cv_inv" << std::endl
477                 #endif
478                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
479                     << "a::const_inv" << std::endl
480                 #endif
481             #endif
482             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
483                 << "a::ctor::post" << std::endl
484             #endif
485         ;
486         BOOST_TEST(out.eq(ok.str()));
487 
488         out.str("");
489         aa.f('a');
490         ok.str(""); ok // Non-cv checks static and const (but not cv) inv.
491             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
492                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
493                     << "b::static_inv" << std::endl
494                 #endif
495                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
496                     << "b::const_inv" << std::endl
497                 #endif
498                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
499                     << "a::static_inv" << std::endl
500                 #endif
501                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
502                     << "a::const_inv" << std::endl
503                 #endif
504             #endif
505             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
506                 << "b::f::pre" << std::endl
507                 << "a::f::pre" << std::endl
508             #endif
509             #ifndef BOOST_CONTRACT_NO_OLDS
510                 << "b::f::old" << std::endl
511                 << "a::f::old" << std::endl
512             #endif
513             << "a::f::body" << std::endl
514             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
515                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
516                     << "b::static_inv" << std::endl
517                 #endif
518                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
519                     << "b::const_inv" << std::endl
520                 #endif
521                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
522                     << "a::static_inv" << std::endl
523                 #endif
524                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
525                     << "a::const_inv" << std::endl
526                 #endif
527             #endif
528             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
529                 << "b::f::old" << std::endl
530                 << "b::f::post" << std::endl
531                 << "a::f::post" << std::endl
532             #endif
533         ;
534         BOOST_TEST(out.eq(ok.str()));
535 
536         out.str("");
537         aa.s(); // Test static call.
538         ok.str(""); ok
539             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
540                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
541                     << "a::static_inv" << std::endl
542                 #endif
543             #endif
544             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
545                 << "a::s::pre" << std::endl
546             #endif
547             #ifndef BOOST_CONTRACT_NO_OLDS
548                 << "a::s::old" << std::endl
549             #endif
550             << "a::s::body" << std::endl
551             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
552                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
553                     << "a::static_inv" << std::endl
554                 #endif
555             #endif
556             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
557                 << "a::s::post" << std::endl
558             #endif
559         ;
560         BOOST_TEST(out.eq(ok.str()));
561 
562         out.str("");
563         aa.call_p(); // Test (indirect) protected call.
564         ok.str(""); ok
565             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
566                 << "a::p::pre" << std::endl
567             #endif
568             #ifndef BOOST_CONTRACT_NO_OLDS
569                 << "a::p::old" << std::endl
570             #endif
571             << "a::p::body" << std::endl
572             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
573                 << "a::p::post" << std::endl
574             #endif
575         ;
576         BOOST_TEST(out.eq(ok.str()));
577 
578         out.str("");
579         aa.call_q(); // Test (indirect) private call.
580         ok.str(""); ok
581             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
582                 << "a::q::pre" << std::endl
583             #endif
584             #ifndef BOOST_CONTRACT_NO_OLDS
585                 << "a::q::old" << std::endl
586             #endif
587             << "a::q::body" << std::endl
588             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
589                 << "a::q::post" << std::endl
590             #endif
591         ;
592         BOOST_TEST(out.eq(ok.str()));
593 
594         out.str("");
595     } // Call a's destructor.
596     ok.str(""); ok // Dtors always check cv_inv (even if not volatile).
597         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
598             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
599                 << "a::static_inv" << std::endl
600             #endif
601             #ifdef BOOST_CONTRACT_TEST_CV_INV
602                 << "a::cv_inv" << std::endl
603             #endif
604             #ifdef BOOST_CONTRACT_TEST_CONST_INV
605                 << "a::const_inv" << std::endl
606             #endif
607         #endif
608         #ifndef BOOST_CONTRACT_NO_OLDS
609             << "a::dtor::old" << std::endl
610         #endif
611         << "a::dtor::body" << std::endl
612         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
613             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
614                 << "a::static_inv" << std::endl
615             #endif
616         #endif
617         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
618             << "a::dtor::post" << std::endl
619         #endif
620 
621         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
622             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
623                 << "b::static_inv" << std::endl
624             #endif
625             #ifdef BOOST_CONTRACT_TEST_CV_INV
626                 << "b::cv_inv" << std::endl
627             #endif
628             #ifdef BOOST_CONTRACT_TEST_CONST_INV
629                 << "b::const_inv" << std::endl
630             #endif
631         #endif
632         #ifndef BOOST_CONTRACT_NO_OLDS
633             << "b::dtor::old" << std::endl
634         #endif
635         << "b::dtor::body" << std::endl
636         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
637             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
638                 << "b::static_inv" << std::endl
639             #endif
640         #endif
641         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
642             << "b::dtor::post" << std::endl
643         #endif
644     ;
645     BOOST_TEST(out.eq(ok.str()));
646 
647 
648     { // Test volatile call with no bases.
649         out.str("");
650         b volatile bv;
651         ok.str(""); ok // Ctors always check const_inv (even if volatile).
652             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
653                 << "b::ctor::pre" << std::endl
654             #endif
655 
656             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
657                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
658                     << "b::static_inv" << std::endl
659                 #endif
660             #endif
661             #ifndef BOOST_CONTRACT_NO_OLDS
662                 << "b::ctor::old" << std::endl
663             #endif
664             << "b::ctor::body" << std::endl
665             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
666                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
667                     << "b::static_inv" << std::endl
668                 #endif
669                 #ifdef BOOST_CONTRACT_TEST_CV_INV
670                     << "b::cv_inv" << std::endl
671                 #endif
672                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
673                     << "b::const_inv" << std::endl
674                 #endif
675             #endif
676             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
677                 << "b::ctor::post" << std::endl
678             #endif
679         ;
680         BOOST_TEST(out.eq(ok.str()));
681 
682         out.str("");
683         bv.f('b');
684         ok.str(""); ok // Volatile checks static and cv (but not const) inv.
685             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
686                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
687                     << "b::static_inv" << std::endl
688                 #endif
689                 #ifdef BOOST_CONTRACT_TEST_CV_INV
690                     << "b::cv_inv" << std::endl
691                 #endif
692             #endif
693             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
694                 << "b::f::volatile_pre" << std::endl
695             #endif
696             #ifndef BOOST_CONTRACT_NO_OLDS
697                 << "b::f::volatile_old" << std::endl
698             #endif
699             << "b::f::volatile_body" << std::endl
700             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
701                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
702                     << "b::static_inv" << std::endl
703                 #endif
704                 #ifdef BOOST_CONTRACT_TEST_CV_INV
705                     << "b::cv_inv" << std::endl
706                 #endif
707             #endif
708             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
709                 << "b::f::volatile_post" << std::endl
710             #endif
711         ;
712         BOOST_TEST(out.eq(ok.str()));
713 
714         out.str("");
715     } // Call b's destructor.
716     ok.str(""); ok // Dtors always check const_inv (even if volatile).
717         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
718             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
719                 << "b::static_inv" << std::endl
720             #endif
721             #ifdef BOOST_CONTRACT_TEST_CV_INV
722                 << "b::cv_inv" << std::endl
723             #endif
724             #ifdef BOOST_CONTRACT_TEST_CONST_INV
725                 << "b::const_inv" << std::endl
726             #endif
727         #endif
728         #ifndef BOOST_CONTRACT_NO_OLDS
729             << "b::dtor::old" << std::endl
730         #endif
731         << "b::dtor::body" << std::endl
732         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
733             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
734                 << "b::static_inv" << std::endl
735             #endif
736         #endif
737         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
738             << "b::dtor::post" << std::endl
739         #endif
740     ;
741     BOOST_TEST(out.eq(ok.str()));
742 
743     { // Test non-volatile call with no bases.
744         out.str("");
745         b bb;
746         ok.str(""); ok // Ctors always check cv_inv (even if not volatile).
747             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
748                 << "b::ctor::pre" << std::endl
749             #endif
750 
751             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
752                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
753                     << "b::static_inv" << std::endl
754                 #endif
755             #endif
756             #ifndef BOOST_CONTRACT_NO_OLDS
757                 << "b::ctor::old" << std::endl
758             #endif
759             << "b::ctor::body" << std::endl
760             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
761                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
762                     << "b::static_inv" << std::endl
763                 #endif
764                 #ifdef BOOST_CONTRACT_TEST_CV_INV
765                     << "b::cv_inv" << std::endl
766                 #endif
767                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
768                     << "b::const_inv" << std::endl
769                 #endif
770             #endif
771             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
772                 << "b::ctor::post" << std::endl
773             #endif
774         ;
775         BOOST_TEST(out.eq(ok.str()));
776 
777         out.str("");
778         bb.f('b');
779         ok.str(""); ok // Non-cv checks static and const (but not cv) inv.
780             #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
781                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
782                     << "b::static_inv" << std::endl
783                 #endif
784                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
785                     << "b::const_inv" << std::endl
786                 #endif
787             #endif
788             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
789                 << "b::f::pre" << std::endl
790             #endif
791             #ifndef BOOST_CONTRACT_NO_OLDS
792                 << "b::f::old" << std::endl
793             #endif
794             << "b::f::body" << std::endl
795             #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
796                 #ifdef BOOST_CONTRACT_TEST_STATIC_INV
797                     << "b::static_inv" << std::endl
798                 #endif
799                 #ifdef BOOST_CONTRACT_TEST_CONST_INV
800                     << "b::const_inv" << std::endl
801                 #endif
802             #endif
803             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
804                 << "b::f::post" << std::endl
805             #endif
806         ;
807         BOOST_TEST(out.eq(ok.str()));
808 
809         out.str("");
810     } // Call b's destructor.
811     ok.str(""); ok // Dtors always check cv_inv (even if not volatile).
812         #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
813             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
814                 << "b::static_inv" << std::endl
815             #endif
816             #ifdef BOOST_CONTRACT_TEST_CV_INV
817                 << "b::cv_inv" << std::endl
818             #endif
819             #ifdef BOOST_CONTRACT_TEST_CONST_INV
820                 << "b::const_inv" << std::endl
821             #endif
822         #endif
823         #ifndef BOOST_CONTRACT_NO_OLDS
824             << "b::dtor::old" << std::endl
825         #endif
826         << "b::dtor::body" << std::endl
827         #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
828             #ifdef BOOST_CONTRACT_TEST_STATIC_INV
829                 << "b::static_inv" << std::endl
830             #endif
831         #endif
832         #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
833             << "b::dtor::post" << std::endl
834         #endif
835     ;
836     BOOST_TEST(out.eq(ok.str()));
837 
838     return boost::report_errors();
839 }
840 
841