• 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 free function contracts.
8 
9 #include "../detail/oteststream.hpp"
10 #include "../detail/counter.hpp"
11 #include <boost/contract/function.hpp>
12 #include <boost/contract/old.hpp>
13 #include <boost/contract/assert.hpp>
14 #include <boost/contract/check.hpp>
15 #include <boost/preprocessor/control/iif.hpp>
16 #include <boost/detail/lightweight_test.hpp>
17 #include <sstream>
18 
19 boost::contract::test::detail::oteststream out;
20 
21 struct x_tag; typedef boost::contract::test::detail::counter<x_tag, int> x_type;
22 struct y_tag; typedef boost::contract::test::detail::counter<y_tag, int> y_type;
23 
swap(x_type & x,y_type & y)24 bool swap(x_type& x, y_type& y) {
25     bool result;
26     boost::contract::old_ptr<x_type> old_x =
27             BOOST_CONTRACT_OLDOF(x_type::eval(x));
28     boost::contract::old_ptr<y_type> old_y;
29     boost::contract::check c = boost::contract::function()
30         .precondition([&] {
31             out << "swap::pre" << std::endl;
32             BOOST_CONTRACT_ASSERT(x.value != y.value);
33         })
34         .old([&] {
35             out << "swap::old" << std::endl;
36             old_y = BOOST_CONTRACT_OLDOF(y_type::eval(y));
37         })
38         .postcondition([&] {
39             out << "swap::post" << std::endl;
40             BOOST_CONTRACT_ASSERT(x.value == old_y->value);
41             BOOST_CONTRACT_ASSERT(y.value == old_x->value);
42             BOOST_CONTRACT_ASSERT(result == (old_x->value != old_y->value));
43         })
44     ;
45 
46     out << "swap::body" << std::endl;
47     if(x.value == y.value) return result = false;
48     int save_x = x.value;
49     x.value = y.value;
50     y.value = save_x;
51     return result = true;
52 }
53 
main()54 int main() {
55     std::ostringstream ok;
56 
57     {
58         x_type x; x.value = 123;
59         y_type y; y.value = 456;
60 
61         out.str("");
62         bool r = swap(x, y);
63         ok.str(""); ok
64             #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
65                 << "swap::pre" << std::endl
66             #endif
67             #ifndef BOOST_CONTRACT_NO_OLDS
68                 << "swap::old" << std::endl
69             #endif
70             << "swap::body" << std::endl
71             #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
72                 << "swap::post" << std::endl
73             #endif
74         ;
75         BOOST_TEST(out.eq(ok.str()));
76 
77         BOOST_TEST(r);
78         BOOST_TEST_EQ(x.value, 456);
79         BOOST_TEST_EQ(y.value, 123);
80     }
81 
82     #ifndef BOOST_CONTRACT_NO_OLDS
83         #define BOOST_CONTRACT_TEST_old 1u
84     #else
85         #define BOOST_CONTRACT_TEST_old 0u
86     #endif
87 
88     BOOST_TEST_EQ(x_type::copies(), BOOST_CONTRACT_TEST_old);
89     BOOST_TEST_EQ(x_type::evals(), BOOST_CONTRACT_TEST_old);
90     BOOST_TEST_EQ(x_type::ctors(), x_type::dtors()); // No leak.
91 
92     BOOST_TEST_EQ(y_type::copies(), BOOST_CONTRACT_TEST_old);
93     BOOST_TEST_EQ(y_type::evals(), BOOST_CONTRACT_TEST_old);
94     BOOST_TEST_EQ(y_type::ctors(), y_type::dtors()); // No leak.
95 
96     #undef BOOST_CONTRACT_TEST_old
97     return boost::report_errors();
98 }
99 
100