blob: a03a821922c9b8049ba563ed32b55d208296d070 [file] [log] [blame]
Brian Silverman1f5d3982018-08-04 23:37:52 -07001//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Antony Polukhin 2014.
4// (C) Copyright Ion Gaztanaga 2014.
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// See http://www.boost.org/libs/move for documentation.
10//
11//////////////////////////////////////////////////////////////////////////////
12#include <boost/move/detail/config_begin.hpp>
13#include <boost/move/utility.hpp>
14#include <boost/core/lightweight_test.hpp>
15#include "../example/movable.hpp"
16#include "../example/copymovable.hpp"
17#include <boost/static_assert.hpp>
18
19//////////////////////////////////////////////////////////////////////////////
20//A copy_movable_noexcept class
21class copy_movable_noexcept
22{
23 BOOST_COPYABLE_AND_MOVABLE(copy_movable_noexcept)
24 int value_;
25
26 public:
27 copy_movable_noexcept() : value_(1){}
28
29 //Move constructor and assignment
30 copy_movable_noexcept(BOOST_RV_REF(copy_movable_noexcept) m)
31 { value_ = m.value_; m.value_ = 0; }
32
33 copy_movable_noexcept(const copy_movable_noexcept &m)
34 { value_ = m.value_; }
35
36 copy_movable_noexcept & operator=(BOOST_RV_REF(copy_movable_noexcept) m)
37 { value_ = m.value_; m.value_ = 0; return *this; }
38
39 copy_movable_noexcept & operator=(BOOST_COPY_ASSIGN_REF(copy_movable_noexcept) m)
40 { value_ = m.value_; return *this; }
41
42 bool moved() const //Observer
43 { return value_ == 0; }
44};
45
46namespace boost{
47
48template<>
49struct has_nothrow_move<copy_movable_noexcept>
50{
51 static const bool value = true;
52};
53
54} //namespace boost{
55
56//////////////////////////////////////////////////////////////////////////////
57//A movable_throwable class
58class movable_throwable
59{
60 BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_throwable)
61 int value_;
62
63 public:
64 movable_throwable() : value_(1){}
65
66 //Move constructor and assignment
67 movable_throwable(BOOST_RV_REF(movable_throwable) m)
68 { value_ = m.value_; m.value_ = 0; }
69
70 movable_throwable & operator=(BOOST_RV_REF(movable_throwable) m)
71 { value_ = m.value_; m.value_ = 0; return *this; }
72
73 bool moved() const //Observer
74 { return !value_; }
75
76 int value() const //Observer
77 { return value_; }
78};
79
80
81//////////////////////////////////////////////////////////////////////////////
82// Helper functions
83movable function(movable m)
84{
85 return movable(boost::move_if_noexcept(m));
86}
87
88copy_movable function(copy_movable m)
89{
90 return copy_movable(boost::move_if_noexcept(m));
91}
92
93copy_movable_noexcept function(copy_movable_noexcept m)
94{
95 return copy_movable_noexcept(boost::move_if_noexcept(m));
96}
97
98movable_throwable function(movable_throwable m)
99{
100 return movable_throwable(boost::move_if_noexcept(m));
101}
102
103movable functionr(BOOST_RV_REF(movable) m)
104{
105 return movable(boost::move_if_noexcept(m));
106}
107
108movable function2(movable m)
109{
110 return boost::move_if_noexcept(m);
111}
112
113BOOST_RV_REF(movable) function2r(BOOST_RV_REF(movable) m)
114{
115 return boost::move_if_noexcept(m);
116}
117
118movable move_return_function2 ()
119{
120 return movable();
121}
122
123movable move_return_function ()
124{
125 movable m;
126 return (boost::move_if_noexcept(m));
127}
128
129#define BOOST_CHECK(x) if (!(x)) { return __LINE__; }
130
131int main()
132{
133 {
134 movable m;
135 movable m2(boost::move_if_noexcept(m));
136 BOOST_CHECK(m.moved());
137 movable m3(function(movable(boost::move_if_noexcept(m2))));
138 BOOST_CHECK(m2.moved());
139 movable m4(function(boost::move_if_noexcept(m3)));
140 BOOST_CHECK(m3.moved());
141 BOOST_CHECK(!m4.moved());
142 }
143 {
144 movable m;
145 movable m2(boost::move_if_noexcept(m));
146 BOOST_CHECK(m.moved());
147 movable m3(functionr(movable(boost::move_if_noexcept(m2))));
148 BOOST_CHECK(m2.moved());
149 movable m4(functionr(boost::move_if_noexcept(m3)));
150 BOOST_CHECK(m3.moved());
151 BOOST_CHECK(!m4.moved());
152 }
153 {
154 movable m;
155 movable m2(boost::move_if_noexcept(m));
156 BOOST_CHECK(m.moved());
157 movable m3(function2(movable(boost::move_if_noexcept(m2))));
158 BOOST_CHECK(m2.moved());
159 movable m4(function2(boost::move_if_noexcept(m3)));
160 BOOST_CHECK(m3.moved());
161 BOOST_CHECK(!m4.moved());
162 }
163 {
164 movable m;
165 movable m2(boost::move_if_noexcept(m));
166 BOOST_CHECK(m.moved());
167 movable m3(function2r(movable(boost::move_if_noexcept(m2))));
168 BOOST_CHECK(m2.moved());
169 movable m4(function2r(boost::move_if_noexcept(m3)));
170 BOOST_CHECK(m3.moved());
171 BOOST_CHECK(!m4.moved());
172 }
173 {
174 movable m;
175 movable m2(boost::move_if_noexcept(m));
176 BOOST_CHECK(m.moved());
177 BOOST_CHECK(!m2.moved());
178 movable m3(move_return_function());
179 BOOST_CHECK(!m3.moved());
180 }
181 {
182 movable m;
183 movable m2(boost::move_if_noexcept(m));
184 BOOST_CHECK(m.moved());
185 BOOST_CHECK(!m2.moved());
186 movable m3(move_return_function2());
187 BOOST_CHECK(!m3.moved());
188 }
189
190 // copy_movable may throw during move, so it must be copied
191 {
192 copy_movable m;
193 copy_movable m2(boost::move_if_noexcept(m));
194 BOOST_CHECK(!m.moved());
195 copy_movable m3(function(copy_movable(boost::move_if_noexcept(m2))));
196 BOOST_CHECK(!m2.moved());
197 copy_movable m4(function(boost::move_if_noexcept(m3)));
198 BOOST_CHECK(!m3.moved());
199 BOOST_CHECK(!m4.moved());
200 }
201
202
203 // copy_movable_noexcept can not throw during move
204 {
205 copy_movable_noexcept m;
206 copy_movable_noexcept m2(boost::move_if_noexcept(m));
207 BOOST_CHECK(m.moved());
208 copy_movable_noexcept m3(function(copy_movable_noexcept(boost::move_if_noexcept(m2))));
209 BOOST_CHECK(m2.moved());
210 copy_movable_noexcept m4(function(boost::move_if_noexcept(m3)));
211 BOOST_CHECK(m3.moved());
212 BOOST_CHECK(!m4.moved());
213 }
214
215 // movable_throwable can not throw during move but it has no copy constructor
216 {
217 movable_throwable m;
218 movable_throwable m2(boost::move_if_noexcept(m));
219 BOOST_CHECK(m.moved());
220 movable_throwable m3(function(movable_throwable(boost::move_if_noexcept(m2))));
221 BOOST_CHECK(m2.moved());
222 movable_throwable m4(function(boost::move_if_noexcept(m3)));
223 BOOST_CHECK(m3.moved());
224 BOOST_CHECK(!m4.moved());
225 }
226
227 return boost::report_errors();
228}
229
230#include <boost/move/detail/config_end.hpp>