]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/contract/example/features/old_if_copyable.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / contract / example / features / old_if_copyable.cpp
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 #include <boost/contract.hpp>
8 #include <boost/type_traits.hpp>
9 #include <boost/noncopyable.hpp>
10 #include <cassert>
11
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()
18 .postcondition([&] {
19 // ...but old value null if T has no copy constructor.
20 if(old_x) BOOST_CONTRACT_ASSERT(x == *old_x + count);
21 })
22 ;
23
24 x += count;
25 }
26 //]
27
28 //[old_if_copyable_w_decl
29 // Copyable type but...
30 class w {
31 public:
32 w(w const&) { /* Some very expensive copy operation here... */ }
33
34 /* ... */
35 //]
36 w() : num_(0) {}
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; }
40 private:
41 unsigned long num_;
42 };
43
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 {
47 template<>
48 struct is_old_value_copyable<w> : boost::false_type {};
49 } }
50 //]
51
52 //[old_if_copyable_p_decl
53 // Non-copyable type but...
54 class p : private boost::noncopyable {
55 int* num_;
56
57 friend struct boost::contract::old_value_copy<p>;
58
59 /* ... */
60 //]
61 public:
62 p() : num_(new int(0)) {}
63 ~p() { delete num_; }
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; }
67 };
68
69 //[old_if_copyable_p_spec
70 // ...still copy old values for type `p` (using a deep copy).
71 namespace boost { namespace contract {
72 template<>
73 struct old_value_copy<p> {
74 explicit old_value_copy(p const& old) {
75 *old_.num_ = *old.num_; // Deep copy pointed value.
76 }
77
78 p const& old() const { return old_; }
79
80 private:
81 p old_;
82 };
83
84 template<>
85 struct is_old_value_copyable<p> : boost::true_type {};
86 } }
87 //]
88
89 //[old_if_copyable_n_decl
90 class n { // Do not want to use boost::noncopyable but...
91 int num_;
92
93 private:
94 n(n const&); // ...unimplemented private copy constructor (so non-copyable).
95
96 /* ... */
97 //]
98
99 public:
100 n() : num_(0) {}
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; }
104 };
105
106 //[old_if_copyable_n_spec
107 // Specialize `boost::is_copy_constructible` (no need for this on C++11).
108 namespace boost { namespace contract {
109 template<>
110 struct is_old_value_copyable<n> : boost::false_type {};
111 } }
112 //]
113
114 int main() {
115 int i = 0; // Copy constructor, copy and check old values.
116 offset(i, 3);
117 assert(i == 3);
118
119 w j; // Expensive copy constructor, so never copy or check old values.
120 offset(j, 3);
121 assert(j == 3);
122
123 p k; // No copy constructor, but still copy and check old values.
124 offset(k, 3);
125 assert(k == 3);
126
127 n h; // No copy constructor, no compiler error but no old value checks.
128 offset(h, 3);
129 assert(h == 3);
130
131 return 0;
132 }
133