• 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 specializations of old value copy type traits.
8 
9 #include <boost/contract/old.hpp>
10 #include <boost/type_traits.hpp>
11 #include <boost/noncopyable.hpp>
12 #include <boost/detail/lightweight_test.hpp>
13 #include <cassert>
14 
15 template<typename T>
f(T & x)16 void f(T& x) {
17     // No OLDOF here so C++11 not required for this test.
18     boost::contract::old_ptr_if_copyable<T> old_x = boost::contract::make_old(
19             boost::contract::copy_old() ? x : boost::contract::null_old());
20 }
21 
22 // Test copyable type but...
23 struct w {
ww24     w() {}
ww25     w(w const&) { BOOST_TEST(false); } // Test this doesn't get copied.
26 };
27 
28 // ...never copy old values for type `w` (because its copy is too expensive).
29 namespace boost { namespace contract {
30     template<>
31     struct is_old_value_copyable<w> : boost::false_type {};
32 } } // namespace
33 
34 // Test non-copyable type but...
35 struct p : private boost::noncopyable { // Non-copyable via Boost.
36     static bool copied;
pp37     p() : num_(new int(0)) {}
~pp38     ~p() { delete num_; }
39 private:
40     int* num_;
41     friend struct boost::contract::old_value_copy<p>;
42 };
43 bool p::copied = false;
44 
45 // ...still copy old values for type `p` (using a deep copy).
46 namespace boost { namespace contract {
47     template<>
48     struct old_value_copy<p> {
old_value_copyboost::contract::old_value_copy49         explicit old_value_copy(p const& old) {
50             *old_.num_ = *old.num_; // Deep copy pointed value.
51             p::copied = true;
52         }
53 
oldboost::contract::old_value_copy54         p const& old() const { return old_; }
55 
56     private:
57         p old_;
58     };
59 
60     template<>
61     struct is_old_value_copyable<p> : boost::true_type {};
62 } } // namespace
63 
64 // Non-copyable type so...
65 struct n {
nn66     n() {}
67 private:
68     n(n const&); // Non-copyable (but not via Boost).
69 };
70 
71 // ...specialize `boost::is_copy_constructible` (no need for this on C++11).
72 namespace boost { namespace contract {
73     template<>
74     struct is_old_value_copyable<n> : boost::false_type {};
75 } } // namespace
76 
main()77 int main() {
78     // NOTE: No test::detail::counter below because that is for copyable types.
79 
80     {
81         int x; // Test has copy ctor so copy olds.
82         f(x);
83     }
84 
85     {
86         w x; // Test has copy ctor but never copy olds (see TEST(...) above).
87         f(x);
88     }
89 
90     p::copied = false;
91     {
92         p x; // Test no copy ctor but still old copies.
93         f(x);
94     }
95     #ifndef BOOST_CONTRACT_NO_OLDS
96         BOOST_TEST(p::copied);
97     #else
98         BOOST_TEST(!p::copied);
99     #endif
100 
101     {
102         n x; // Test no copy ctor so no old copies.
103         f(x);
104     }
105 
106     return boost::report_errors();
107 }
108 
109