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
7 #include <boost/contract.hpp>
8 #include <boost/type_traits.hpp>
9 #include <boost/noncopyable.hpp>
12 //[old_if_copyable_offset
13 template<typename T> // T might or might not be copyable.
14 void offset(T& x, int count) {
15 // No compiler error if T has no copy constructor...
16 boost::contract::old_ptr_if_copyable<T> old_x = BOOST_CONTRACT_OLDOF(x);
17 boost::contract::check c = boost::contract::function()
19 // ...but old value null if T has no copy constructor.
20 if(old_x) BOOST_CONTRACT_ASSERT(x == *old_x + count);
28 //[old_if_copyable_w_decl
29 // Copyable type but...
32 w(w const&) { /* Some very expensive copy operation here... */ }
37 int operator+(int i) const { return num_ + i; }
38 w& operator+=(int i) { num_ += i; return *this; }
39 bool operator==(int i) const { return long(num_) == i; }
44 //[old_if_copyable_w_spec
45 // ...never copy old values for type `w` (because its copy is too expensive).
46 namespace boost { namespace contract {
48 struct is_old_value_copyable<w> : boost::false_type {};
52 //[old_if_copyable_p_decl
53 // Non-copyable type but...
54 class p : private boost::noncopyable {
57 friend struct boost::contract::old_value_copy<p>;
62 p() : num_(new int(0)) {}
64 int operator+(int i) const { return *num_ + i; }
65 p& operator+=(int i) { *num_ += i; return *this; }
66 bool operator==(int i) const { return *num_ == i; }
69 //[old_if_copyable_p_spec
70 // ...still copy old values for type `p` (using a deep copy).
71 namespace boost { namespace contract {
73 struct old_value_copy<p> {
74 explicit old_value_copy(p const& old) {
75 *old_.num_ = *old.num_; // Deep copy pointed value.
78 p const& old() const { return old_; }
85 struct is_old_value_copyable<p> : boost::true_type {};
89 //[old_if_copyable_n_decl
90 class n { // Do not want to use boost::noncopyable but...
94 n(n const&); // ...unimplemented private copy constructor (so non-copyable).
101 int operator+(int i) const { return num_ + i; }
102 n& operator+=(int i) { num_ += i; return *this; }
103 bool operator==(int i) const { return num_ == i; }
106 //[old_if_copyable_n_spec
107 // Specialize `boost::is_copy_constructible` (no need for this on C++11).
108 namespace boost { namespace contract {
110 struct is_old_value_copyable<n> : boost::false_type {};
115 int i = 0; // Copy constructor, copy and check old values.
119 w j; // Expensive copy constructor, so never copy or check old values.
123 p k; // No copy constructor, but still copy and check old values.
127 n h; // No copy constructor, no compiler error but no old value checks.