// Copyright (C) 2008-2018 Lorenzo Caminiti // Distributed under the Boost Software License, Version 1.0 (see accompanying // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html // Test old values of non-copyable types. #include "if_copyable.hpp" #include #include #include #include #include #include #include #include #include unsigned old_checks; template struct b { virtual void next(T& x, boost::contract::virtual_* v = 0) { boost::contract::old_ptr_if_copyable old_x = BOOST_CONTRACT_OLDOF(v, x); boost::contract::check c = boost::contract::public_function(v, this) .postcondition([&] { if(old_x) { BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); ++old_checks; } }) ; ++x; } BOOST_CONTRACT_OVERRIDE(next) }; template struct a #define BASES public b : BASES { typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #undef BASES virtual void next(T& x, boost::contract::virtual_* v = 0) /* override */ { boost::contract::old_ptr_if_copyable old_x = BOOST_CONTRACT_OLDOF(v, x); boost::contract::check c = boost::contract::public_function< override_next>(v, &a::next, this, x) .postcondition([&] { if(old_x) { BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); ++old_checks; } }) ; ++x; } BOOST_CONTRACT_OVERRIDE(next) }; template void next(T& x) { boost::contract::old_ptr_if_copyable old_x = BOOST_CONTRACT_OLDOF(x); boost::contract::check c = boost::contract::function() .postcondition([&] { if(old_x) { BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); ++old_checks; } }) ; ++x; } int main() { int i = 1; // Test built-in copyable type. cp c(1); // Test custom copyable type. ncp n(1); // Test non-copyable type. // Test free functions (old values without `v`). unsigned cnt = #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 1 #else 0 #endif ; old_checks = 0; next(i); BOOST_TEST_EQ(old_checks, cnt); old_checks = 0; next(c); BOOST_TEST_EQ(old_checks, cnt); old_checks = 0; next(n); BOOST_TEST_EQ(old_checks, 0u); // Test virtual functions (old values with `v`). cnt = #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS 2 #else 0 #endif ; a ai; old_checks = 0; ai.next(i); BOOST_TEST_EQ(old_checks, cnt); a ac; old_checks = 0; ac.next(c); BOOST_TEST_EQ(old_checks, cnt); a an; old_checks = 0; an.next(n); BOOST_TEST_EQ(old_checks, 0u); return boost::report_errors(); }