diff options
Diffstat (limited to 'src/boost/libs/contract/test/old/copyable_traits.cpp')
-rw-r--r-- | src/boost/libs/contract/test/old/copyable_traits.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/boost/libs/contract/test/old/copyable_traits.cpp b/src/boost/libs/contract/test/old/copyable_traits.cpp new file mode 100644 index 00000000..3792c6fe --- /dev/null +++ b/src/boost/libs/contract/test/old/copyable_traits.cpp @@ -0,0 +1,108 @@ + +// 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 specializations of old value copy type traits. + +#include <boost/contract/old.hpp> +#include <boost/type_traits.hpp> +#include <boost/noncopyable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> + +template<typename T> +void f(T& x) { + // No OLDOF here so C++11 not required for this test. + boost::contract::old_ptr_if_copyable<T> old_x = boost::contract::make_old( + boost::contract::copy_old() ? x : boost::contract::null_old()); +} + +// Test copyable type but... +struct w { + w() {} + w(w const&) { BOOST_TEST(false); } // Test this doesn't get copied. +}; + +// ...never copy old values for type `w` (because its copy is too expensive). +namespace boost { namespace contract { + template<> + struct is_old_value_copyable<w> : boost::false_type {}; +} } // namespace + +// Test non-copyable type but... +struct p : private boost::noncopyable { // Non-copyable via Boost. + static bool copied; + p() : num_(new int(0)) {} + ~p() { delete num_; } +private: + int* num_; + friend struct boost::contract::old_value_copy<p>; +}; +bool p::copied = false; + +// ...still copy old values for type `p` (using a deep copy). +namespace boost { namespace contract { + template<> + struct old_value_copy<p> { + explicit old_value_copy(p const& old) { + *old_.num_ = *old.num_; // Deep copy pointed value. + p::copied = true; + } + + p const& old() const { return old_; } + + private: + p old_; + }; + + template<> + struct is_old_value_copyable<p> : boost::true_type {}; +} } // namespace + +// Non-copyable type so... +struct n { + n() {} +private: + n(n const&); // Non-copyable (but not via Boost). +}; + +// ...specialize `boost::is_copy_constructible` (no need for this on C++11). +namespace boost { namespace contract { + template<> + struct is_old_value_copyable<n> : boost::false_type {}; +} } // namespace + +int main() { + // NOTE: No test::detail::counter below because that is for copyable types. + + { + int x; // Test has copy ctor so copy olds. + f(x); + } + + { + w x; // Test has copy ctor but never copy olds (see TEST(...) above). + f(x); + } + + p::copied = false; + { + p x; // Test no copy ctor but still old copies. + f(x); + } + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST(p::copied); + #else + BOOST_TEST(!p::copied); + #endif + + { + n x; // Test no copy ctor so no old copies. + f(x); + } + + return boost::report_errors(); +} + |