]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/contract/example/features/move.cpp
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>
13 class circular_buffer
:
14 private boost::contract::constructor_precondition
<circular_buffer
> {
16 void invariant() const {
17 if(!moved()) { // Do not check (some) invariants for moved-from objects.
18 BOOST_CONTRACT_ASSERT(index() < size());
20 // More invariants here that hold also for moved-from objects (e.g.,
21 // all assertions necessary to successfully destroy moved-from objects).
25 circular_buffer(circular_buffer
&& other
) :
26 boost::contract::constructor_precondition
<circular_buffer
>([&] {
27 BOOST_CONTRACT_ASSERT(!other
.moved());
30 boost::contract::check c
= boost::contract::constructor(this)
32 BOOST_CONTRACT_ASSERT(!moved());
33 BOOST_CONTRACT_ASSERT(other
.moved());
37 move(std::forward
<circular_buffer
>(other
));
41 circular_buffer
& operator=(circular_buffer
&& other
) {
42 // Moved-from can be (move) assigned (so no pre `!moved()` here).
43 boost::contract::check c
= boost::contract::public_function(this)
45 BOOST_CONTRACT_ASSERT(!other
.moved());
48 BOOST_CONTRACT_ASSERT(!moved());
49 BOOST_CONTRACT_ASSERT(other
.moved());
53 return move(std::forward
<circular_buffer
>(other
));
57 // Moved-from can always be destroyed (in fact no preconditions).
58 boost::contract::check c
= boost::contract::destructor(this);
62 boost::contract::check c
= boost::contract::public_function(this);
73 explicit circular_buffer(std::vector
<char> const& data
,
75 boost::contract::constructor_precondition
<circular_buffer
>([&] {
76 BOOST_CONTRACT_ASSERT(start
< data
.size());
82 boost::contract::check c
= boost::contract::constructor(this)
84 BOOST_CONTRACT_ASSERT(!moved());
90 circular_buffer(circular_buffer
const& other
) :
91 boost::contract::constructor_precondition
<circular_buffer
>([&] {
92 BOOST_CONTRACT_ASSERT(!other
.moved());
95 boost::contract::check c
= boost::contract::constructor(this)
97 BOOST_CONTRACT_ASSERT(!moved());
105 circular_buffer
& operator=(circular_buffer
const& other
) {
106 // Moved-from can be (copy) assigned (so no pre `!moved()` here).
107 boost::contract::check c
= boost::contract::public_function(this)
109 BOOST_CONTRACT_ASSERT(!other
.moved());
112 BOOST_CONTRACT_ASSERT(!moved());
120 boost::contract::check c
= boost::contract::public_function(this)
122 BOOST_CONTRACT_ASSERT(!moved());
126 unsigned i
= index_
++;
127 if(index_
== data_
.size()) index_
= 0; // Circular.
132 circular_buffer
& copy(circular_buffer
const& other
) {
134 index_
= other
.index_
;
139 circular_buffer
& move(circular_buffer
&& other
) {
140 data_
= std::move(other
.data_
);
141 index_
= std::move(other
.index_
);
143 other
.moved_
= true; // Mark moved-from object.
147 std::vector
<char> data_
;
151 unsigned index() const {
152 boost::contract::check c
= boost::contract::public_function(this);
156 unsigned size() const {
157 boost::contract::check c
= boost::contract::public_function(this);
164 boost::contract::set_precondition_failure(
165 [] (boost::contract::from
) { throw err(); });
168 circular_buffer
x({'a', 'b', 'c', 'd'}, 2);
169 assert(x
.read() == 'c');
171 circular_buffer y1
= x
; // Copy constructor.
172 assert(y1
.read() == 'd');
173 assert(x
.read() == 'd');
175 circular_buffer
y2({'h'});
176 y2
= x
; // Copy assignment.
177 assert(y2
.read() == 'a');
178 assert(x
.read() == 'a');
180 circular_buffer z1
= std::move(x
); // Move constructor.
181 assert(z1
.read() == 'b');
182 // Calling `x.read()` would fail `!moved()` precondition.
184 x
= y1
; // Moved-from `x` can be copy assigned.
185 assert(x
.read() == 'a');
186 assert(y1
.read() == 'a');
188 circular_buffer
z2({'k'});
189 z2
= std::move(x
); // Move assignment.
190 assert(z2
.read() == 'b');
191 // Calling `x.read()` would fail `!moved()` precondition.
193 x
= std::move(y2
); // Moved-from `x` can be move assigned.
194 assert(x
.read() == 'b');
195 // Calling `y2.read()` would fail `!moved()` precondition.
197 } // Moved-from `y2` can be destroyed.