diff options
Diffstat (limited to 'src/boost/libs/contract/test/old/if_copyable.cpp')
-rw-r--r-- | src/boost/libs/contract/test/old/if_copyable.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/boost/libs/contract/test/old/if_copyable.cpp b/src/boost/libs/contract/test/old/if_copyable.cpp new file mode 100644 index 00000000..0c3738f3 --- /dev/null +++ b/src/boost/libs/contract/test/old/if_copyable.cpp @@ -0,0 +1,133 @@ + +// 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 <boost/contract/public_function.hpp> +#include <boost/contract/function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/noncopyable.hpp> +#include <boost/detail/lightweight_test.hpp> + +unsigned old_checks; + +template<typename T> +struct b { + virtual void next(T& x, boost::contract::virtual_* v = 0) { + boost::contract::old_ptr_if_copyable<T> 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<typename T> +struct a + #define BASES public b<T> + : 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<T> 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<typename T> +void next(T& x) { + boost::contract::old_ptr_if_copyable<T> 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<int> ai; + old_checks = 0; + ai.next(i); + BOOST_TEST_EQ(old_checks, cnt); + + a<cp> ac; + old_checks = 0; + ac.next(c); + BOOST_TEST_EQ(old_checks, cnt); + + a<ncp> an; + old_checks = 0; + an.next(n); + BOOST_TEST_EQ(old_checks, 0u); + + return boost::report_errors(); +} + |