summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/contract/test/old/copyable_traits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/contract/test/old/copyable_traits.cpp')
-rw-r--r--src/boost/libs/contract/test/old/copyable_traits.cpp108
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();
+}
+